blob: 6daad531ad4fa1d5cd89047817371431f229a4f5 [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;
Harald Weltedbd5e672021-01-14 21:03:14 +0100600 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200601
602 var BSSGP_ConnHdlrPars pars := {
603 imei := f_gen_imei(imsi_suffix),
604 imsi := f_gen_imsi(imsi_suffix),
605 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100606 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200607 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100608 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200609 tlli_old := omit,
610 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100611 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100612 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200613 t_guard := t_guard
614 };
615
616 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200617
618 vc_conn.start(f_handler_init(fn, id, pars));
619 return vc_conn;
620}
621
Harald Welte3dd21b32020-11-17 19:21:00 +0100622/* 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 +0100623private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
624runs on BSSGP_ConnHdlr {
625 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100626 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100627 /* unregister + disconnect from old BVC */
628 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100629 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100630 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
631 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
632 }
633 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100634 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100635 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
636 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
637 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
638 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100639 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100640}
641
642/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
643private 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 +0100644 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100645 /* unregister + disconnect from old BVC */
646 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100647 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100648 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
649 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
650 }
651 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100652 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100653 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
654 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
655 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
656 sgsn_ct[port_idx] := bvc_ct;
657}
658
Harald Welte425d3762020-12-09 14:33:18 +0100659private altstep as_gTguard(timer Tguard) {
660 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200661 setverdict(fail, "Tguard timeout");
662 mtc.stop;
663 }
664}
665
666/* first function called in every ConnHdlr */
667private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
668runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100669 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200670 /* do some common stuff like setting up g_pars */
671 g_pars := pars;
672
673 llc := f_llc_create(false);
674
Harald Welte3dd21b32020-11-17 19:21:00 +0100675 /* default connections on PCU side: First BVC of each NSE/PCU */
676 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100677 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100678 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100679
680 /* default connections on SGSN side: First BVC of each NSE/SGSN */
681 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
682 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100683 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200684
685 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100686 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200687
688 /* call the user-supplied test case function */
689 fn.apply(id);
690}
691
Harald Welte1e834f32020-11-15 20:02:59 +0100692private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
693runs on BSSGP_ConnHdlr {
694 PT.call(BSSGP_register_client:{imsi, tlli}) {
695 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
696 }
697}
698
699private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
700runs on BSSGP_ConnHdlr {
701 PT.call(BSSGP_unregister_client:{imsi}) {
702 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
703 }
704}
705
Harald Welte22ef5d92020-11-16 13:35:14 +0100706/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
707friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100708 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100709 var PDU_BSSGP rx;
710 timer T := 1.0;
711
Daniel Willmann4798fd72020-11-24 16:23:29 +0100712 if (use_sig) {
713 PCU_SIG[pcu_idx].send(tx);
714 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100715 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100716 }
717
Harald Welte22ef5d92020-11-16 13:35:14 +0100718 T.start;
719 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100720 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
721 setverdict(pass);
722 }
Harald Welte158becf2020-12-09 12:32:32 +0100723 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100724 setverdict(pass);
725 }
Harald Welte158becf2020-12-09 12:32:32 +0100726 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100727 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
728 mtc.stop;
729 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100730 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
731 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
732 mtc.stop;
733 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100734 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100735 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100736 mtc.stop;
737 }
738 }
739}
740
741/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
742friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100743 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100744 var PDU_BSSGP rx;
745 timer T := 1.0;
746
Daniel Willmann4798fd72020-11-24 16:23:29 +0100747 if (use_sig) {
748 SGSN_SIG[sgsn_idx].send(tx);
749 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100750 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100751 }
752
Harald Welte22ef5d92020-11-16 13:35:14 +0100753 T.start;
754 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100755 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
756 setverdict(pass);
757 }
Harald Welte158becf2020-12-09 12:32:32 +0100758 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100759 setverdict(pass);
760 }
Harald Welte158becf2020-12-09 12:32:32 +0100761 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100762 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
763 mtc.stop;
764 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100765 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
766 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
767 mtc.stop;
768 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100769 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100770 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100771 mtc.stop;
772 }
773 }
774}
Harald Welte1e834f32020-11-15 20:02:59 +0100775
Harald Welte3807ed12020-11-24 19:05:22 +0100776/***********************************************************************
777 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
778 ***********************************************************************/
779
780type component GlobalTest_CT extends test_CT {
781 port BSSGP_PT G_PCU[NUM_PCU];
782 port BSSGP_PT G_SGSN[NUM_SGSN];
783};
784
Harald Welte299aa482020-12-09 15:10:55 +0100785/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100786private function f_global_init() runs on GlobalTest_CT {
787 var integer i;
788 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
789 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
790 }
791 for (i := 0; i < lengthof(g_pcu); i := i+1) {
792 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
793 }
794}
795
Harald Welte299aa482020-12-09 15:10:55 +0100796/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
797private function f_global_init_ptp() runs on GlobalTest_CT {
798 var integer i;
799 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
800 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
801 }
802 for (i := 0; i < lengthof(g_pcu); i := i+1) {
803 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
804 }
805}
806
Harald Welte3807ed12020-11-24 19:05:22 +0100807/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
808friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
809 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
810 var PDU_BSSGP rx;
811 timer T := 1.0;
812
813 G_PCU[pcu_idx].send(tx);
814 T.start;
815 alt {
816 [] G_SGSN[sgsn_idx].receive(exp_rx) {
817 setverdict(pass);
818 }
819 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
820 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
821 mtc.stop;
822 }
823 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100824 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100825 mtc.stop;
826 }
827 }
828}
829
830/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
831friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
832 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
833 var PDU_BSSGP rx;
834 timer T := 1.0;
835
836 G_SGSN[sgsn_idx].send(tx);
837 T.start;
838 alt {
839 [] G_PCU[pcu_idx].receive(exp_rx) {
840 setverdict(pass);
841 }
842 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
843 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
844 mtc.stop;
845 }
846 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100847 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100848 mtc.stop;
849 }
850 }
851}
852
853
Daniel Willmann423d8f42020-09-08 18:58:22 +0200854/* TODO:
855 * Detach without Attach
856 * SM procedures without attach / RAU
857 * ATTACH / RAU
858 ** with / without authentication
859 ** with / without P-TMSI allocation
860 * re-transmissions of LLC frames
861 * PDP Context activation
862 ** with different GGSN config in SGSN VTY
863 ** with different PDP context type (v4/v6/v46)
864 ** timeout from GGSN
865 ** multiple / secondary PDP context
866 */
867
868private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
869 f_sleep(5.0);
870 setverdict(pass);
871}
872
873testcase TC_BVC_bringup() runs on test_CT {
874 var BSSGP_ConnHdlr vc_conn;
875 f_init();
876
877 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
878 vc_conn.done;
879
880 f_cleanup();
881}
882
883friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100884 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200885 timer T := 5.0;
886 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100887 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200888 T.start;
889 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100890 [] 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 +0200891 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
892 }
Harald Welte16357a92020-11-17 18:20:00 +0100893 [] 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 +0200894 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
895 mtc.stop;
896 }
897 [] T.timeout {
898 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
899 mtc.stop;
900 }
901 }
902 return '00'O;
903}
904
905friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100906 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200907 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100908 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 +0200909 T.start;
910 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100911 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
912 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200913 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
914 mtc.stop;
915 }
916 [] T.timeout {
917 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
918 mtc.stop;
919 }
920 }
921}
922
923
Harald Welte92686012020-11-15 21:45:49 +0100924/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
925private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100926 var integer ran_idx := 0;
927 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100928 var integer i;
929
Harald Welte0d5fceb2020-11-29 16:04:07 +0100930 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100931 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100932 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 +0100933 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100934 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 +0100935
Harald Welte0d5fceb2020-11-29 16:04:07 +0100936 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100937 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100938 }
939 setverdict(pass);
940}
941
942testcase TC_ul_unitdata() runs on test_CT
943{
944 var BSSGP_ConnHdlr vc_conn;
945 f_init();
946
947 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
948 vc_conn.done;
949 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
950
951 f_cleanup();
952}
953
Harald Welte78d8db92020-11-15 23:27:27 +0100954/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
955private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
956 var integer i;
957
Harald Welte0d5fceb2020-11-29 16:04:07 +0100958 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100959 var octetstring payload := f_rnd_octstring(i);
960 var template (value) PDU_BSSGP pdu_tx :=
961 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
962 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
963 var template (present) PDU_BSSGP pdu_rx :=
964 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
965
Harald Welte0d5fceb2020-11-29 16:04:07 +0100966 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100967 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100968 }
969 setverdict(pass);
970}
971
972testcase TC_dl_unitdata() runs on test_CT
973{
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976
977 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
978 vc_conn.done;
979 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
980
981 f_cleanup();
982}
Harald Welte92686012020-11-15 21:45:49 +0100983
Harald Welte6dc2ac42020-11-16 09:16:17 +0100984private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
985 var integer i;
986
987 for (i := 0; i < 10; i := i+1) {
988 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
989 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
990 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
991
Harald Welte22ef5d92020-11-16 13:35:14 +0100992 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100993 }
994 setverdict(pass);
995}
996testcase TC_ra_capability() runs on test_CT
997{
998 var BSSGP_ConnHdlr vc_conn;
999 f_init();
1000
1001 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
1002 vc_conn.done;
1003 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1004
1005 f_cleanup();
1006}
1007
Daniel Willmannace3ece2020-11-16 19:53:26 +01001008private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1009 var integer i;
1010 var OCT1 tag;
1011 for (i := 0; i < 10; i := i+1) {
1012 tag := int2oct(23 + i, 1);
1013 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1014 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1015 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1016
1017 f_pcu2sgsn(pdu_tx, pdu_rx);
1018
1019 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1020 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1021 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1022
1023 f_sgsn2pcu(pdu_tx, pdu_rx);
1024 }
1025 setverdict(pass);
1026}
1027testcase TC_ra_capability_upd() runs on test_CT
1028{
1029 var BSSGP_ConnHdlr vc_conn;
1030 f_init();
1031
Daniel Willmann54833f22020-11-19 15:43:52 +01001032 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001033 vc_conn.done;
1034 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1035
1036 f_cleanup();
1037}
1038
Daniel Willmann165d6612020-11-19 14:27:29 +01001039private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1040 var integer i;
1041 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1042 for (i := 0; i < 10; i := i+1) {
1043 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1044 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1045 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1046
1047 f_pcu2sgsn(pdu_tx, pdu_rx);
1048 }
1049 setverdict(pass);
1050}
1051testcase TC_radio_status() runs on test_CT
1052{
1053 var BSSGP_ConnHdlr vc_conn;
1054 f_init();
1055
Daniel Willmann54833f22020-11-19 15:43:52 +01001056 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001057 vc_conn.done;
1058 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1059
1060 f_cleanup();
1061}
1062
Harald Welte3807ed12020-11-24 19:05:22 +01001063private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001064 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001065
Daniel Willmannfa67f492020-11-19 15:48:05 +01001066 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001067 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001068 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001069 var OCT4 tlli := f_gprs_tlli_random();
1070 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001071 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001072 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001073
Harald Welte3807ed12020-11-24 19:05:22 +01001074 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001075
Harald Welte3807ed12020-11-24 19:05:22 +01001076 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001077 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001078 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001079
Harald Welte3807ed12020-11-24 19:05:22 +01001080 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001081
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001082 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1083 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1084 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1085
1086 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1087
Daniel Willmannfa67f492020-11-19 15:48:05 +01001088 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001089 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001090 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001091 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001092
Harald Welte3807ed12020-11-24 19:05:22 +01001093 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001094 }
1095 setverdict(pass);
1096}
Harald Welte3807ed12020-11-24 19:05:22 +01001097testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001098{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001099 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001100 f_global_init();
1101 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001102 f_cleanup();
1103}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001104
Harald Welte3807ed12020-11-24 19:05:22 +01001105private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001106 var integer i;
1107
1108 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001109 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001110 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001111 var OCT4 tlli := f_gprs_tlli_random();
1112 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001113 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001114 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001115
Harald Welte3807ed12020-11-24 19:05:22 +01001116 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001117
Harald Welte3807ed12020-11-24 19:05:22 +01001118 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001119 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001120 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001121
Harald Welte3807ed12020-11-24 19:05:22 +01001122 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001123
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001124 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1125 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1126 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1127
1128 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1129
Daniel Willmann087a33d2020-11-19 15:58:43 +01001130 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001131 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001132 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001133 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001134
Harald Welte3807ed12020-11-24 19:05:22 +01001135 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001136 }
1137 setverdict(pass);
1138}
Harald Welte3807ed12020-11-24 19:05:22 +01001139testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001140{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001141 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001142 f_global_init();
1143 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001144 f_cleanup();
1145}
1146
Harald Weltef8ef0282020-11-18 12:16:59 +01001147/* test the load-sharing between multiple NS-VC on the BSS side */
1148private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1149 var integer i;
1150
1151 for (i := 0; i < 10; i := i+1) {
1152 var octetstring payload := f_rnd_octstring(i);
1153 var template (value) PDU_BSSGP pdu_tx :=
1154 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001155 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001156 }
1157 setverdict(pass);
1158}
1159testcase TC_load_sharing_dl() runs on test_CT_NS
1160{
1161 const integer num_ue := 10;
1162 var BSSGP_ConnHdlr vc_conn[num_ue];
1163 f_init();
1164
1165 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1166 * side so we get the raw NsUnitdataIndication and hence observe different
1167 * NSVCI */
1168 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1169 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1170
1171 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1172 * of the NS-VC is ALIVE/UNBLOCKED */
1173 f_sleep(3.0);
1174
1175 /* start parallel components generating DL-UNITDATA from the SGSN side */
1176 for (var integer i:= 0; i < num_ue; i := i+1) {
1177 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1178 }
1179
1180 /* now start counting all the messages that were queued before */
1181 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1182 var ro_integer rx_count := { 0, 0, 0, 0 };
1183 timer T := 2.0;
1184 T.start;
1185 alt {
1186 [] as_NsUdiCount(0, rx_count);
1187 [] as_NsUdiCount(1, rx_count);
1188 [] as_NsUdiCount(2, rx_count);
1189 [] as_NsUdiCount(3, rx_count);
1190 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1191 [] NS.receive(NsStatusIndication:?) { repeat; }
1192 [] NS.receive {
1193 setverdict(fail, "Rx unexpected NS");
1194 mtc.stop;
1195 }
1196 [] T.timeout {
1197 }
1198 }
1199 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1200 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1201 if (rx_count[i] == 0) {
1202 setverdict(fail, "Data not shared over all NSVC");
1203 }
1204 }
1205 setverdict(pass);
1206}
1207private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1208 var NsUnitdataIndication udi;
1209 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1210 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1211 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1212 repeat;
1213 }
1214}
1215type component test_CT_NS extends test_CT {
1216 port NS_PT NS;
1217};
1218
1219
Harald Welte0e188242020-11-22 21:46:48 +01001220/***********************************************************************
1221 * PAGING PS procedure
1222 ***********************************************************************/
1223
1224private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1225 boolean use_sig := false)
1226runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1227 var template (value) PDU_BSSGP pdu_tx;
1228 var template (present) PDU_BSSGP pdu_rx;
1229 /* we always specify '0' as BVCI in the templates below, as we override it with
1230 * 'p4' later anyway */
1231 pdu_rx := tr_BSSGP_PS_PAGING(0);
1232 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1233 if (ispresent(g_pars.p_tmsi)) {
1234 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1235 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1236 } else {
1237 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1238 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1239 }
1240 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1241 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1242 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001243 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001244 } else {
1245 SGSN_SIG[sgsn_idx].send(pdu_tx);
1246 }
1247 return pdu_rx;
1248}
1249
1250/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1251 * specified PCU index */
1252private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1253 boolean use_sig := false,integer pcu_idx := 0)
1254runs on BSSGP_ConnHdlr {
1255 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001256 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001257 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1258 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1259 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1260 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1261 timer T := 2.0;
1262 T.start;
1263 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001264 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001265 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001266 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001267 repeat;
1268 }
1269 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1270 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1271 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001272 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001273 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001274 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001275 repeat;
1276 }
Harald Welte158becf2020-12-09 12:32:32 +01001277 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001278 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1279 }
Harald Welte158becf2020-12-09 12:32:32 +01001280 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001281 setverdict(fail, "Paging received on unexpected BVC");
1282 }
1283 [] any from PCU_SIG.receive(exp_rx) {
1284 setverdict(fail, "Paging received on unexpected BVC");
1285 }
Harald Welte158becf2020-12-09 12:32:32 +01001286 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001287 setverdict(fail, "Different Paging than expected received PTP BVC");
1288 }
1289 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1290 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1291 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001292 [not test_done] T.timeout {
1293 setverdict(fail, "Timeout waiting for paging");
1294 }
1295 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001296 }
1297}
1298
Harald Welte7462a592020-11-23 22:07:07 +01001299/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1300private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1301 boolean use_sig := false)
1302runs on BSSGP_ConnHdlr {
1303 var template (present) PDU_BSSGP exp_rx;
1304 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1305 /* Expect paging to propagate to no BSS */
1306 timer T := 2.0;
1307 T.start;
1308 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001309 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001310 setverdict(fail, "Paging received on unexpected BVC");
1311 }
1312 [] any from PCU_SIG.receive(exp_rx) {
1313 setverdict(fail, "Paging received on unexpected BVC");
1314 }
Harald Welte158becf2020-12-09 12:32:32 +01001315 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001316 setverdict(fail, "Different Paging received on PTP BVC");
1317 }
1318 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1319 setverdict(fail, "Different Paging received on SIGNALING BVC");
1320 }
1321 [] T.timeout {
1322 setverdict(pass);
1323 }
1324 }
1325}
1326
Harald Welte0e188242020-11-22 21:46:48 +01001327private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1328{
1329 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1330 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1331 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1332}
1333testcase TC_paging_ps_ptp_bss() runs on test_CT {
1334 var BSSGP_ConnHdlr vc_conn;
1335 f_init();
1336
1337 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1338 vc_conn.done;
1339
1340 f_cleanup();
1341}
1342
1343/* PS-PAGING on PTP-BVC for Location Area */
1344private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1345{
1346 var template (present) PDU_BSSGP exp_rx;
1347 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1348 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1349 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1350}
1351testcase TC_paging_ps_ptp_lac() runs on test_CT {
1352 var BSSGP_ConnHdlr vc_conn;
1353 f_init();
1354
1355 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1356 vc_conn.done;
1357
1358 f_cleanup();
1359}
1360
Harald Welte7462a592020-11-23 22:07:07 +01001361/* PS-PAGING on PTP-BVC for unknown Location Area */
1362private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1363{
1364 var GSM_Types.LocationAreaIdentification unknown_la := {
1365 mcc_mnc := '567F99'H,
1366 lac := 33333
1367 };
1368 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1369 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1370}
1371testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1372 var BSSGP_ConnHdlr vc_conn;
1373 f_init();
1374
1375 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1376 vc_conn.done;
1377
1378 f_cleanup();
1379}
1380
Harald Welte0e188242020-11-22 21:46:48 +01001381/* PS-PAGING on PTP-BVC for Routeing Area */
1382private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1383{
1384 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1385 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1386 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1387}
1388testcase TC_paging_ps_ptp_rac() runs on test_CT {
1389 var BSSGP_ConnHdlr vc_conn;
1390 f_init();
1391
1392 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1393 vc_conn.done;
1394
1395 f_cleanup();
1396}
1397
Harald Welte7462a592020-11-23 22:07:07 +01001398/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1399private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1400{
1401 var RoutingAreaIdentification unknown_ra := {
1402 lai := {
1403 mcc_mnc := '567F99'H,
1404 lac := 33333
1405 },
1406 rac := 254
1407 };
1408 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1409 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1410}
1411testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1412 var BSSGP_ConnHdlr vc_conn;
1413 f_init();
1414
1415 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1416 vc_conn.done;
1417
1418 f_cleanup();
1419}
1420
Harald Welte0e188242020-11-22 21:46:48 +01001421/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1422private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1423{
1424 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1425 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1426}
1427testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1428 var BSSGP_ConnHdlr vc_conn;
1429 f_init();
1430
1431 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1432 vc_conn.done;
1433
1434 f_cleanup();
1435}
1436
Harald Welte7462a592020-11-23 22:07:07 +01001437/* PS-PAGING on PTP-BVC for unknown BVCI */
1438private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1439{
1440 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1441 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1442}
1443testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1444 var BSSGP_ConnHdlr vc_conn;
1445 f_init();
1446
1447 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1448 vc_conn.done;
1449
1450 f_cleanup();
1451}
1452
Harald Welte0e188242020-11-22 21:46:48 +01001453/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1454private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1455runs on BSSGP_ConnHdlr {
1456[] PCU_SIG[pcu_idx].receive(exp_rx) {
1457 if (ro_integer_contains(roi, pcu_idx)) {
1458 setverdict(fail, "Received multiple paging on same SIG BVC");
1459 }
1460 roi := roi & { pcu_idx };
1461 repeat;
1462 }
Harald Welte158becf2020-12-09 12:32:32 +01001463[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001464 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1465 }
1466[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1467 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1468 }
Harald Welte158becf2020-12-09 12:32:32 +01001469[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001470 setverdict(fail, "Different Paging than expected received PTP BVC");
1471 }
1472}
1473
1474type record of default ro_default;
1475
1476/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1477private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1478 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1479{
1480 var template (present) PDU_BSSGP exp_rx;
1481 exp_rx := f_send_paging_ps(p4, 0, true);
1482
1483 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1484 var ro_default defaults := {};
1485 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1486 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1487 defaults := defaults & { d };
1488 }
1489 f_sleep(2.0);
1490 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1491 deactivate(defaults[i]);
1492 }
1493 log("Paging received on PCU ", g_roi);
1494
1495 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1496 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1497 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1498 if (exp_on_i and not rx_on_i) {
1499 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1500 }
1501 if (not exp_on_i and rx_on_i) {
1502 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1503 }
1504 }
1505 setverdict(pass);
1506}
1507
1508/* PS-PAGING on SIG-BVC for BSS Area */
1509private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1510{
1511 /* we expect the paging to arrive on all three NSE */
1512 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1513}
1514testcase TC_paging_ps_sig_bss() runs on test_CT {
1515 var BSSGP_ConnHdlr vc_conn;
1516 f_init();
1517
1518 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1519 vc_conn.done;
1520
1521 f_cleanup();
1522}
1523
1524/* PS-PAGING on SIG-BVC for Location Area */
1525private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1526{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001527 /* The first LAC (13135) is shared by all three NSEs */
1528 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1529 /* Reset state */
1530 g_roi := {};
1531 /* Make LAC (13300) available on pcu index 2 */
1532 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1533 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 +01001534}
1535testcase TC_paging_ps_sig_lac() runs on test_CT {
1536 var BSSGP_ConnHdlr vc_conn;
1537 f_init();
1538
1539 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1540 vc_conn.done;
1541
1542 f_cleanup();
1543}
1544
Harald Welte7462a592020-11-23 22:07:07 +01001545/* PS-PAGING on SIG-BVC for unknown Location Area */
1546private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1547{
1548 var GSM_Types.LocationAreaIdentification unknown_la := {
1549 mcc_mnc := '567F99'H,
1550 lac := 33333
1551 };
1552 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1553}
1554testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1555 var BSSGP_ConnHdlr vc_conn;
1556 f_init();
1557
1558 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1559 vc_conn.done;
1560
1561 f_cleanup();
1562}
1563
Harald Welte0e188242020-11-22 21:46:48 +01001564/* PS-PAGING on SIG-BVC for Routeing Area */
1565private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1566{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001567 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001568 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 +01001569 g_roi := {};
1570 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1571 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1572 g_roi := {};
1573 /* PCU index 2 has two matching BVCs with the RA ID */
1574 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1575 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 +01001576}
1577testcase TC_paging_ps_sig_rac() runs on test_CT {
1578 var BSSGP_ConnHdlr vc_conn;
1579 f_init();
1580
1581 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1582 vc_conn.done;
1583
1584 f_cleanup();
1585}
1586
Harald Welte7462a592020-11-23 22:07:07 +01001587/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1588private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1589{
1590 var RoutingAreaIdentification unknown_ra := {
1591 lai := {
1592 mcc_mnc := '567F99'H,
1593 lac := 33333
1594 },
1595 rac := 254
1596 };
1597 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1598}
1599testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1600 var BSSGP_ConnHdlr vc_conn;
1601 f_init();
1602
1603 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1604 vc_conn.done;
1605
1606 f_cleanup();
1607}
1608
Harald Welte0e188242020-11-22 21:46:48 +01001609/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1610private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1611{
1612 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1613}
1614testcase TC_paging_ps_sig_bvci() runs on test_CT {
1615 var BSSGP_ConnHdlr vc_conn;
1616 f_init();
1617
1618 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1619 vc_conn.done;
1620
1621 f_cleanup();
1622}
1623
Harald Welte7462a592020-11-23 22:07:07 +01001624/* PS-PAGING on SIG-BVC for unknown BVCI */
1625private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1626{
1627 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1628}
1629testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1630 var BSSGP_ConnHdlr vc_conn;
1631 f_init();
1632
1633 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1634 vc_conn.done;
1635
1636 f_cleanup();
1637}
1638
1639
Harald Welte0e188242020-11-22 21:46:48 +01001640
1641/***********************************************************************
1642 * PAGING CS procedure
1643 ***********************************************************************/
1644
1645private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1646 boolean use_sig := false)
1647runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1648 var template (value) PDU_BSSGP pdu_tx;
1649 var template (present) PDU_BSSGP pdu_rx;
1650 /* we always specify '0' as BVCI in the templates below, as we override it with
1651 * 'p4' later anyway */
1652 pdu_rx := tr_BSSGP_CS_PAGING(0);
1653 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1654 if (ispresent(g_pars.p_tmsi)) {
1655 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1656 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1657 } else {
1658 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1659 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1660 }
1661 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1662 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1663 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001664 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001665 } else {
1666 SGSN_SIG[sgsn_idx].send(pdu_tx);
1667 }
1668 return pdu_rx;
1669}
1670
1671/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1672 * specified PCU index */
1673private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1674 boolean use_sig := false,integer pcu_idx := 0)
1675runs on BSSGP_ConnHdlr {
1676 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001677 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001678 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1679 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1680 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1681 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1682 timer T := 2.0;
1683 T.start;
1684 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001685 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001686 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001687 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001688 repeat;
1689 }
1690 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1691 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1692 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001693 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001694 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001695 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001696 repeat;
1697 }
Harald Welte158becf2020-12-09 12:32:32 +01001698 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001699 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1700 }
Harald Welte158becf2020-12-09 12:32:32 +01001701 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001702 setverdict(fail, "Paging received on unexpected BVC");
1703 }
1704 [] any from PCU_SIG.receive(exp_rx) {
1705 setverdict(fail, "Paging received on unexpected BVC");
1706 }
Harald Welte158becf2020-12-09 12:32:32 +01001707 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001708 setverdict(fail, "Different Paging than expected received PTP BVC");
1709 }
1710 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1711 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1712 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001713 [not test_done] T.timeout {
1714 setverdict(fail, "Timeout while waiting for paging")
1715 }
1716 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001717 }
1718}
1719
Harald Welte7462a592020-11-23 22:07:07 +01001720/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1721private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1722 boolean use_sig := false)
1723runs on BSSGP_ConnHdlr {
1724 var template (present) PDU_BSSGP exp_rx;
1725 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1726 /* Expect paging to propagate to no BSS */
1727 timer T := 2.0;
1728 T.start;
1729 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001730 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001731 setverdict(fail, "Paging received on unexpected BVC");
1732 }
1733 [] any from PCU_SIG.receive(exp_rx) {
1734 setverdict(fail, "Paging received on unexpected BVC");
1735 }
Harald Welte158becf2020-12-09 12:32:32 +01001736 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001737 setverdict(fail, "Different Paging received on PTP BVC");
1738 }
1739 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1740 setverdict(fail, "Different Paging received on SIGNALING BVC");
1741 }
1742 [] T.timeout {
1743 setverdict(pass);
1744 }
1745 }
1746}
1747
Harald Welte0e188242020-11-22 21:46:48 +01001748private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1749{
1750 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1751 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1752 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1753}
1754testcase TC_paging_cs_ptp_bss() runs on test_CT {
1755 var BSSGP_ConnHdlr vc_conn;
1756 f_init();
1757
1758 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1759 vc_conn.done;
1760
1761 f_cleanup();
1762}
1763
1764/* CS-PAGING on PTP-BVC for Location Area */
1765private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1766{
1767 var template (present) PDU_BSSGP exp_rx;
1768 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1769 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1770 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1771}
1772testcase TC_paging_cs_ptp_lac() runs on test_CT {
1773 var BSSGP_ConnHdlr vc_conn;
1774 f_init();
1775
1776 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1777 vc_conn.done;
1778
1779 f_cleanup();
1780}
1781
Harald Welte7462a592020-11-23 22:07:07 +01001782/* CS-PAGING on PTP-BVC for unknown Location Area */
1783private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1784{
1785 var GSM_Types.LocationAreaIdentification unknown_la := {
1786 mcc_mnc := '567F99'H,
1787 lac := 33333
1788 };
1789 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1790 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1791}
1792testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1793 var BSSGP_ConnHdlr vc_conn;
1794 f_init();
1795
1796 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1797 vc_conn.done;
1798
1799 f_cleanup();
1800}
1801
Harald Welte0e188242020-11-22 21:46:48 +01001802/* CS-PAGING on PTP-BVC for Routeing Area */
1803private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1804{
1805 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1806 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1807 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1808}
1809testcase TC_paging_cs_ptp_rac() runs on test_CT {
1810 var BSSGP_ConnHdlr vc_conn;
1811 f_init();
1812
1813 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1814 vc_conn.done;
1815
1816 f_cleanup();
1817}
1818
Harald Welte7462a592020-11-23 22:07:07 +01001819/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1820private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1821{
1822 var RoutingAreaIdentification unknown_ra := {
1823 lai := {
1824 mcc_mnc := '567F99'H,
1825 lac := 33333
1826 },
1827 rac := 254
1828 };
1829 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1830 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1831}
1832testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1833 var BSSGP_ConnHdlr vc_conn;
1834 f_init();
1835
1836 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1837 vc_conn.done;
1838
1839 f_cleanup();
1840}
1841
Harald Welte0e188242020-11-22 21:46:48 +01001842/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1843private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1844{
1845 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1846 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1847}
1848testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1849 var BSSGP_ConnHdlr vc_conn;
1850 f_init();
1851
1852 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1853 vc_conn.done;
1854
1855 f_cleanup();
1856}
1857
Harald Welte7462a592020-11-23 22:07:07 +01001858/* CS-PAGING on PTP-BVC for unknown BVCI */
1859private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1860{
1861 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1862 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1863}
1864testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1865 var BSSGP_ConnHdlr vc_conn;
1866 f_init();
1867
1868 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1869 vc_conn.done;
1870
1871 f_cleanup();
1872}
1873
Harald Welte0e188242020-11-22 21:46:48 +01001874/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1875private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1876 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1877{
1878 var template (present) PDU_BSSGP exp_rx;
1879 exp_rx := f_send_paging_cs(p4, 0, true);
1880
1881 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1882 var ro_default defaults := {};
1883 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1884 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1885 defaults := defaults & { d };
1886 }
1887 f_sleep(2.0);
1888 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1889 deactivate(defaults[i]);
1890 }
1891 log("Paging received on PCU ", g_roi);
1892
1893 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1894 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1895 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1896 if (exp_on_i and not rx_on_i) {
1897 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1898 }
1899 if (not exp_on_i and rx_on_i) {
1900 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1901 }
1902 }
1903 setverdict(pass);
1904}
1905
1906/* CS-PAGING on SIG-BVC for BSS Area */
1907private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1908{
1909 /* we expect the paging to arrive on all three NSE */
1910 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1911}
1912testcase TC_paging_cs_sig_bss() runs on test_CT {
1913 var BSSGP_ConnHdlr vc_conn;
1914 f_init();
1915
1916 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1917 vc_conn.done;
1918
1919 f_cleanup();
1920}
1921
1922/* CS-PAGING on SIG-BVC for Location Area */
1923private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1924{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001925 /* The first LAC (13135) is shared by all three NSEs */
1926 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1927 /* Reset state */
1928 g_roi := {};
1929 /* Make LAC (13300) available on pcu index 2 */
1930 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1931 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 +01001932}
1933testcase TC_paging_cs_sig_lac() runs on test_CT {
1934 var BSSGP_ConnHdlr vc_conn;
1935 f_init();
1936
1937 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1938 vc_conn.done;
1939
1940 f_cleanup();
1941}
1942
Harald Welte7462a592020-11-23 22:07:07 +01001943/* CS-PAGING on SIG-BVC for unknown Location Area */
1944private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1945{
1946 var GSM_Types.LocationAreaIdentification unknown_la := {
1947 mcc_mnc := '567F99'H,
1948 lac := 33333
1949 };
1950 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1951}
1952testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1953 var BSSGP_ConnHdlr vc_conn;
1954 f_init();
1955
1956 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1957 vc_conn.done;
1958
1959 f_cleanup();
1960}
1961
Harald Welte0e188242020-11-22 21:46:48 +01001962/* CS-PAGING on SIG-BVC for Routeing Area */
1963private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1964{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001965 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001966 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 +01001967 g_roi := {};
1968 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1969 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1970 g_roi := {};
1971 /* PCU index 2 has two matching BVCs with the RA ID */
1972 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1973 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 +01001974}
1975testcase TC_paging_cs_sig_rac() runs on test_CT {
1976 var BSSGP_ConnHdlr vc_conn;
1977 f_init();
1978
1979 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1980 vc_conn.done;
1981
1982 f_cleanup();
1983}
1984
Harald Welte7462a592020-11-23 22:07:07 +01001985/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1986private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1987{
1988 var RoutingAreaIdentification unknown_ra := {
1989 lai := {
1990 mcc_mnc := '567F99'H,
1991 lac := 33333
1992 },
1993 rac := 254
1994 };
1995 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1996}
1997testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1998 var BSSGP_ConnHdlr vc_conn;
1999 f_init();
2000
2001 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
2002 vc_conn.done;
2003
2004 f_cleanup();
2005}
2006
Harald Welte0e188242020-11-22 21:46:48 +01002007/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2008private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2009{
2010 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2011}
2012testcase TC_paging_cs_sig_bvci() runs on test_CT {
2013 var BSSGP_ConnHdlr vc_conn;
2014 f_init();
2015
2016 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
2017 vc_conn.done;
2018
2019 f_cleanup();
2020}
2021
Harald Welte7462a592020-11-23 22:07:07 +01002022/* CS-PAGING on SIG-BVC for unknown BVCI */
2023private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2024{
2025 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2026}
2027testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
2028 var BSSGP_ConnHdlr vc_conn;
2029 f_init();
2030
2031 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
2032 vc_conn.done;
2033
2034 f_cleanup();
2035}
2036
Harald Welte4f91c3b2020-12-09 12:25:51 +01002037/***********************************************************************
2038 * FLUSH-LL procedure
2039 ***********************************************************************/
2040
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002041private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2042 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2043 var integer i;
2044 for (i := 0; i < 10; i := i+1) {
2045 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2046 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2047 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2048
2049 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2050
2051 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2053 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2054
2055 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2056 }
2057 setverdict(pass);
2058}
2059testcase TC_flush_ll() runs on test_CT
2060{
2061 var BSSGP_ConnHdlr vc_conn;
2062 f_init();
2063
2064 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2065 vc_conn.done;
2066 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2067
2068 f_cleanup();
2069}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002070
Harald Welte4f91c3b2020-12-09 12:25:51 +01002071/***********************************************************************
2072 * SGSN-INVOKE-TRACE procedure
2073 ***********************************************************************/
2074
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002075private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2076runs on GlobalTest_CT {
2077[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2078 if (ro_integer_contains(roi, pcu_idx)) {
2079 setverdict(fail, "Received multiple on same SIG BVC");
2080 }
2081 roi := roi & { pcu_idx };
2082 repeat;
2083 }
2084}
2085/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2086testcase TC_trace() runs on GlobalTest_CT
2087{
2088 var BSSGP_ConnHdlr vc_conn;
2089 f_init();
2090 f_global_init();
2091
2092 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2093 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2094
2095 var ro_default defaults := {};
2096 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2097 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2098 }
2099 G_SGSN[0].send(pdu_tx);
2100 f_sleep(2.0);
2101 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2102 deactivate(defaults[i]);
2103 }
2104
2105 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2106 if (not ro_integer_contains(g_roi, i)) {
2107 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2108 }
2109 }
2110 setverdict(pass);
2111
2112 f_cleanup();
2113}
2114
Harald Welte4f91c3b2020-12-09 12:25:51 +01002115/***********************************************************************
2116 * LLC-DISCARDED procedure
2117 ***********************************************************************/
2118
Harald Weltec0351d12020-11-27 22:49:02 +01002119private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2120 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2121
2122 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2123 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2124 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2125
2126 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2127
2128 setverdict(pass);
2129}
2130/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2131testcase TC_llc_discarded() runs on test_CT
2132{
2133 var BSSGP_ConnHdlr vc_conn;
2134 f_init();
2135
2136 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2137 vc_conn.done;
2138 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2139
2140 f_cleanup();
2141}
2142
Harald Welte4f91c3b2020-12-09 12:25:51 +01002143/***********************************************************************
2144 * OVERLOAD procedure
2145 ***********************************************************************/
2146
Harald Weltef20af412020-11-28 16:11:11 +01002147/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2148testcase TC_overload() runs on GlobalTest_CT
2149{
2150 f_init();
2151 f_global_init();
2152
2153 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2154 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2155
2156 var ro_default defaults := {};
2157 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2158 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2159 }
2160 G_SGSN[0].send(pdu_tx);
2161 f_sleep(2.0);
2162 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2163 deactivate(defaults[i]);
2164 }
2165
2166 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2167 if (not ro_integer_contains(g_roi, i)) {
2168 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2169 }
2170 }
2171 setverdict(pass);
2172
2173 f_cleanup();
2174}
2175
Harald Welte4f91c3b2020-12-09 12:25:51 +01002176/***********************************************************************
2177 * BVC-BLOCK / BVC-UNBLOCK procedure
2178 ***********************************************************************/
2179
Harald Welte239aa502020-11-24 23:14:20 +01002180private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2181{
2182 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2183 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2184 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2185
2186 SGSN_MGMT.clear;
2187 PCU_MGMT.clear;
2188
2189 /* block the PTP BVC from the PCU side */
2190 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2191 /* expect state on both PCU and SGSN side to change */
2192 interleave {
2193 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2194 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2195 }
2196 setverdict(pass);
2197}
2198testcase TC_bvc_block_ptp() runs on test_CT
2199{
2200 f_init();
2201 f_sleep(1.0);
2202 f_block_ptp_bvc_from_pcu(0, 0);
2203 f_cleanup();
2204}
2205
2206private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2207{
2208 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2209 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2210 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2211
2212 SGSN_MGMT.clear;
2213 PCU_MGMT.clear;
2214
2215 /* block the PTP BVC from the PCU side */
2216 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2217 /* expect state on both PCU and SGSN side to change */
2218 interleave {
2219 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2220 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2221 }
2222 setverdict(pass);
2223}
2224testcase TC_bvc_unblock_ptp() runs on test_CT
2225{
2226 f_init();
2227 f_sleep(1.0);
2228 f_block_ptp_bvc_from_pcu(0, 0);
2229 f_sleep(1.0);
2230 f_unblock_ptp_bvc_from_pcu(0, 0);
2231 f_cleanup();
2232}
2233
Harald Welte4f91c3b2020-12-09 12:25:51 +01002234/***********************************************************************
2235 * BVC-RESET procedure
2236 ***********************************************************************/
2237
Harald Welte60a8ec72020-11-25 17:12:53 +01002238private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2239[] pt.receive(BssgpStatusIndication:?) { repeat; }
2240}
2241private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2242 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2243 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2244 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2245 }
2246 }
2247 return null;
2248}
2249private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2250{
2251 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2252 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2253 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2254 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2255 var default d;
2256
2257 SGSN_MGMT.clear;
2258 PCU_MGMT.clear;
2259
2260 /* block the PTP BVC from the PCU side */
2261 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2262 /* expect state on both PCU and SGSN side to change */
2263 d := activate(as_ignore_status(SGSN_MGMT));
2264 interleave {
2265 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2266 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2267 }
2268 deactivate(d);
2269 setverdict(pass);
2270}
2271/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2272testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2273{
2274 f_init();
2275 f_sleep(3.0);
2276 f_reset_ptp_bvc_from_pcu(0, 0);
2277 f_cleanup();
2278}
2279
Harald Welte16786e92020-11-27 19:11:56 +01002280private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2281runs on test_CT {
2282 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2283 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2284 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002285 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002286 }
2287}
2288/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2289testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2290
2291 f_init();
2292 f_sleep(3.0);
2293
2294 /* Start BVC-RESET procedure for BVCI=0 */
2295 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2296
2297 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2298 var ro_default defaults := {};
2299 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2300 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2301 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2302 defaults := defaults & { d };
2303 }
2304
2305 timer T := 3.0;
2306 T.start;
2307 alt {
2308 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2309 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2310 }
2311 [] T.timeout;
2312 }
2313
2314 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2315 deactivate(defaults[i]);
2316 }
2317
2318 /* check if BVC-block was received on all expected BVC */
2319 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2320 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2321 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2322 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2323 }
2324 }
2325
2326 /* check if BVC-block was not received on any unexpected BVC is not required as
2327 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002328 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002329 f_cleanup();
2330}
2331
Harald Welte60a8ec72020-11-25 17:12:53 +01002332private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2333{
2334 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2335 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2336 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2337 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2338 var default d;
2339
2340 SGSN_MGMT.clear;
2341 PCU_MGMT.clear;
2342
2343 /* block the PTP BVC from the PCU side */
2344 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2345 /* expect state on both PCU and SGSN side to change */
2346 d := activate(as_ignore_status(PCU_MGMT));
2347 interleave {
2348 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2349 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2350 }
2351 deactivate(d);
2352 setverdict(pass);
2353}
2354/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2355testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2356{
2357 f_init();
2358 f_sleep(3.0);
2359 f_reset_ptp_bvc_from_sgsn(0, 0);
2360 f_cleanup();
2361}
2362
Daniel Willmannef7015f2021-01-08 00:43:56 +01002363private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2364 [] pt.receive {repeat; }
2365}
2366
Harald Welte16786e92020-11-27 19:11:56 +01002367private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2368runs on test_CT {
2369 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2370 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2371 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002372 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002373 }
2374}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002375
Harald Welte16786e92020-11-27 19:11:56 +01002376/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2377testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2378
2379 f_init();
2380 f_sleep(3.0);
2381
Daniel Willmannef7015f2021-01-08 00:43:56 +01002382 SGSN_MGMT.clear;
2383 PCU_MGMT.clear;
2384
Harald Welte16786e92020-11-27 19:11:56 +01002385 /* Start BVC-RESET procedure for BVCI=0 */
2386 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2387
Daniel Willmannef7015f2021-01-08 00:43:56 +01002388 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2389 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2390 * the port and a different message sits at the front we wait forever and fail the test.
2391 */
2392 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2393
Harald Welte16786e92020-11-27 19:11:56 +01002394 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002395 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2396 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2397 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2398 defaults := defaults & { d };
2399 }
2400
2401 f_sleep(3.0);
2402
2403 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2404 deactivate(defaults[i]);
2405 }
2406
2407 /* check if BVC-block was received on all expected BVC */
2408 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2409 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2410 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2411 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2412 }
2413 }
2414
2415 /* check if BVC-block was not received on any unexpected BVC is not required as
2416 * such a message would basically run into 'no matching clause' */
2417
2418 f_cleanup();
2419}
2420
Harald Welte299aa482020-12-09 15:10:55 +01002421/***********************************************************************
2422 * FLOW-CONTROL-BVC procedure
2423 ***********************************************************************/
2424
2425private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2426 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2427runs on GlobalTest_CT {
2428 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2429 roi := roi & { sgsn_idx };
2430 if (ispresent(tx_reply)) {
2431 G_SGSN[sgsn_idx].send(tx_reply);
2432 }
2433 }
2434}
2435/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2436testcase TC_fc_bvc() runs on GlobalTest_CT
2437{
2438 f_init();
2439 f_global_init_ptp();
2440
2441 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2442 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2443 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2444 var template (omit) PDU_BSSGP ack_tx :=
2445 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2446
2447 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2448 G_PCU[0].send(pdu_tx);
2449
2450 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2451 var ro_default defaults := {};
2452 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2453 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2454 defaults := defaults & { d };
2455 }
2456
2457 f_sleep(3.0);
2458
2459 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2460 deactivate(defaults[i]);
2461 }
2462
2463 /* check if BVC-block was received on all expected BVC */
2464 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2465 if (not ro_integer_contains(g_roi, i)) {
2466 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2467 }
2468 }
2469
2470 /* Expect ACK on PCU side */
2471 G_PCU[0].receive(ack_tx);
2472
2473 setverdict(pass);
2474
2475 f_cleanup();
2476}
2477
Harald Weltecc3894b2020-12-09 16:50:12 +01002478/***********************************************************************
2479 * FLOW-CONTROL-MS procedure
2480 ***********************************************************************/
2481
2482private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2483 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2484
2485 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2486 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2487 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2488 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2489
2490 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2491 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2492
2493 setverdict(pass);
2494}
2495/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2496testcase TC_fc_ms() runs on test_CT
2497{
2498 var BSSGP_ConnHdlr vc_conn;
2499 f_init();
2500
2501 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2502 vc_conn.done;
2503 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2504
2505 f_cleanup();
2506}
2507
2508
Harald Welte299aa482020-12-09 15:10:55 +01002509
Daniel Willmann423d8f42020-09-08 18:58:22 +02002510control {
2511 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002512 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002513 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002514 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002515 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002516 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002517 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002518 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002519 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002520 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002521 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002522 execute( TC_bvc_block_ptp() );
2523 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002524 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002525 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002526 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002527 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002528 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002529 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2530 execute( TC_load_sharing_dl() );
2531 }
Harald Welte0e188242020-11-22 21:46:48 +01002532
2533 /* PAGING-PS over PTP BVC */
2534 execute( TC_paging_ps_ptp_bss() );
2535 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002536 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002537 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002538 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002539 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002540 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002541
2542 /* PAGING-PS over SIG BVC */
2543 execute( TC_paging_ps_sig_bss() );
2544 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002545 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002546 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002547 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002548 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002549 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002550
2551 /* PAGING-CS over PTP BVC */
2552 execute( TC_paging_cs_ptp_bss() );
2553 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002554 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002555 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002556 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002557 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002558 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002559
2560 /* PAGING-CS over SIG BVC */
2561 execute( TC_paging_cs_sig_bss() );
2562 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002563 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002564 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002565 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002566 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002567 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002568
2569
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002570 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002571 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002572 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002573}
2574
2575
2576}