blob: 6141f6ac786d34325ba0bf7707bd2748e9b3b6b0 [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 Welte77218d02021-01-15 19:59:15 +010048 /* NRI bit-length. 0 for no pooling */
49 integer mp_nri_bitlength := 5;
50 roro_integer mp_sgsn_nri := {
51 { 3 }, /* list of NRIs of first SGSN */
52 { 4 } /* list of NRIs of second SGSN */
53 };
Harald Weltef6e59b02020-12-08 08:29:09 +010054 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010055 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010056 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020057 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 nsei := 101,
59 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010060 handle_sns := false,
61 nsvc := {
62 {
63 provider := {
64 ip := {
65 address_family := AF_INET,
66 local_udp_port := 7777,
67 local_ip := "127.0.0.1",
68 remote_udp_port := 23000,
69 remote_ip := "127.0.0.1"
70 }
71 },
72 nsvci := 101
73 }
74 }
Harald Welteb978ed62020-12-12 14:01:11 +010075 }, {
76 nsei := 102,
77 role_sgsn := true,
78 handle_sns := false,
79 nsvc := {
80 {
81 provider := {
82 ip := {
83 address_family := AF_INET,
84 local_udp_port := 8888,
85 local_ip := "127.0.0.1",
86 remote_udp_port := 23000,
87 remote_ip := "127.0.0.1"
88 }
89 },
90 nsvci := 102
91 }
92 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020093 }
94 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010095 /* BSS NSEI start at 2000 + x
96 * NSVCI start from value of NSEI + 100
97 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010098 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020099 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100100 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200101 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100102 handle_sns := false,
103 nsvc := {
104 {
105 provider := {
106 ip := {
107 address_family := AF_INET,
108 local_udp_port := 21010,
109 local_ip := "127.0.0.1",
110 remote_udp_port := 23000,
111 remote_ip := "127.0.0.1"
112 }
113 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100114 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100115 }
116 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200117 },
118 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100119 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200120 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100121 handle_sns := false,
122 nsvc := {
123 {
124 provider := {
125 ip := {
126 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100128 local_ip := "127.0.0.1",
129 remote_udp_port := 23000,
130 remote_ip := "127.0.0.1"
131 }
132 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100133 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100134 }
135 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200136 },
137 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100138 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200139 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100140 handle_sns := false,
141 nsvc := {
142 {
143 provider := {
144 ip := {
145 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100146 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100147 local_ip := "127.0.0.1",
148 remote_udp_port := 23000,
149 remote_ip := "127.0.0.1"
150 }
151 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100152 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100153 }
154 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200155 }
156 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100157 /* BVCI are NSEI*10 + x
158 * The first NSE only has one BVC, the second one 2 and so on
159 * The Cell ID is BVCI + 10000
160 * LAC/RAC are configured in such a way that:
161 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
162 * LAC 13300 is present twice in NSE(2003)
163 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
164 * RAI 13300-0 is present twice in NSE(2003)
165 */
Harald Welte6d63f742020-11-15 19:44:04 +0100166 BssgpConfigs mp_gbconfigs := {
167 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100168 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100169 sgsn_role := false,
170 bvc := {
171 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100172 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100173 cell_id := {
174 ra_id := {
175 lai := {
176 mcc_mnc := c_mcc_mnc,
177 lac := 13135
178 },
179 rac := 0
180 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100181 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100182 },
183 depth := BSSGP_DECODE_DEPTH_BSSGP,
184 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
185 }
186 }
187 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100188 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100189 sgsn_role := false,
190 bvc := {
191 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100192 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100193 cell_id := {
194 ra_id := {
195 lai := {
196 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100197 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100198 },
Harald Welte0e188242020-11-22 21:46:48 +0100199 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100200 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100201 cell_id := 30021
202 },
203 depth := BSSGP_DECODE_DEPTH_BSSGP,
204 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
205 },
206 {
207 bvci := 20022,
208 cell_id := {
209 ra_id := {
210 lai := {
211 mcc_mnc := c_mcc_mnc,
212 lac := 13135
213 },
214 rac := 2
215 },
216 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100217 },
218 depth := BSSGP_DECODE_DEPTH_BSSGP,
219 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
220 }
221 }
222 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100223 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100224 sgsn_role := false,
225 bvc := {
226 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100227 bvci := 20031,
228 cell_id := {
229 ra_id := {
230 lai := {
231 mcc_mnc := c_mcc_mnc,
232 lac := 13135
233 },
234 rac := 1
235 },
236 cell_id := 30031
237 },
238 depth := BSSGP_DECODE_DEPTH_BSSGP,
239 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
240 },
241 {
242 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100243 cell_id := {
244 ra_id := {
245 lai := {
246 mcc_mnc := c_mcc_mnc,
247 lac := 13300
248 },
249 rac := 0
250 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100251 cell_id := 30032
252 },
253 depth := BSSGP_DECODE_DEPTH_BSSGP,
254 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
255 },
256 {
257 bvci := 20033,
258 cell_id := {
259 ra_id := {
260 lai := {
261 mcc_mnc := c_mcc_mnc,
262 lac := 13300
263 },
264 rac := 0
265 },
266 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100267 },
268 depth := BSSGP_DECODE_DEPTH_BSSGP,
269 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
270 }
271 }
272 }
273 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200274};
275
Daniel Willmann423d8f42020-09-08 18:58:22 +0200276type record GbInstance {
277 NS_CT vc_NS,
278 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100279 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200280 BssgpConfig cfg
281};
Harald Welte67dc8c22020-11-17 18:32:29 +0100282type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200283
284const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100285type record of GbInstance GbInstances;
286type record of BssgpConfig BssgpConfigs;
287type record of NSConfiguration NSConfigurations;
288type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200289
Harald Welteb978ed62020-12-12 14:01:11 +0100290const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200291
292type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100293 var GbInstances g_pcu;
294 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200295
296 port BSSGP_CT_PROC_PT PROC;
297
Harald Weltefbae83f2020-11-15 23:25:55 +0100298 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
299 port BSSGP_BVC_MGMT_PT PCU_MGMT;
300
Daniel Willmann423d8f42020-09-08 18:58:22 +0200301 port TELNETasp_PT GBPVTY;
302
303 var boolean g_initialized := false;
304 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100305
306 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100307 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200308};
309
310type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100311 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100312 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200313 port BSSGP_PT PCU_SIG[NUM_PCU];
314 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100315 /* component reference to the component to which we're currently connected */
316 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100317 /* BSSGP BVC configuration of the component to which we're currently connected */
318 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100319
320 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100321 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200322 port BSSGP_PT SGSN_SIG[NUM_SGSN];
323 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100324 /* component reference to the component to which we're currently connected */
325 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200326
327 var BSSGP_ConnHdlrPars g_pars;
328 timer g_Tguard;
329 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100330
331 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200332}
333
334type record SGSN_ConnHdlrNetworkPars {
335 boolean expect_ptmsi,
336 boolean expect_auth,
337 boolean expect_ciph
338};
339
340type record BSSGP_ConnHdlrPars {
341 /* IMEI of the simulated ME */
342 hexstring imei,
343 /* IMSI of the simulated MS */
344 hexstring imsi,
345 /* MSISDN of the simulated MS (probably unused) */
346 hexstring msisdn,
347 /* P-TMSI allocated to the simulated MS */
348 OCT4 p_tmsi optional,
349 OCT3 p_tmsi_sig optional,
350 /* TLLI of the simulated MS */
351 OCT4 tlli,
352 OCT4 tlli_old optional,
353 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100354 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100355 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100356 /* The SGSN index to be used within the test */
357 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200358 float t_guard
359};
360
361private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
362 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
363 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
364
365 var RoutingAreaIdentificationV ret := {
366 mccDigit1 := mcc_mnc[0],
367 mccDigit2 := mcc_mnc[1],
368 mccDigit3 := mcc_mnc[2],
369 mncDigit3 := mcc_mnc[3],
370 mncDigit1 := mcc_mnc[4],
371 mncDigit2 := mcc_mnc[5],
372 lac := int2oct(cell_id.ra_id.lai.lac, 16),
373 rac := int2oct(cell_id.ra_id.rac, 8)
374 }
375 return ret;
376};
377
Harald Welte95339432020-12-02 18:50:52 +0100378private function f_fix_create_cb(inout BssgpConfig cfg)
379{
380 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
381 if (not isbound(cfg.bvc[i].create_cb)) {
382 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
383 }
384 }
385}
386
Daniel Willmann423d8f42020-09-08 18:58:22 +0200387private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100388 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
389 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
390 gb.vc_NS := NS_CT.create(ns_id);
391 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200392 /* connect lower end of BSSGP emulation with NS upper port */
393 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
394
Harald Welteb419d0e2020-11-16 16:45:05 +0100395 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
396 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397
398 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100399 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200400 connect(self:PROC, gb.vc_BSSGP:PROC);
401 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
402 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100403 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100404 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200405 }
Harald Welteb978ed62020-12-12 14:01:11 +0100406 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100407 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200408}
409
410private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100411 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
412 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
413 gb.vc_NS := NS_CT.create(ns_id);
414 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200415 /* connect lower end of BSSGP emulation with NS upper port */
416 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
417
Harald Welteb419d0e2020-11-16 16:45:05 +0100418 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
419 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200420
421 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100422 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200423 connect(self:PROC, gb.vc_BSSGP:PROC);
424 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
425 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100426 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100427 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200428 }
Harald Welteb978ed62020-12-12 14:01:11 +0100429 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100430 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200431}
432
433
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100434private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
435 gb.vc_NS.stop;
436 gb.vc_BSSGP.stop;
437
438 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
439 gb.vc_BSSGP_BVC[i].stop;
440 }
441}
442
Daniel Willmann423d8f42020-09-08 18:58:22 +0200443private function f_init_vty() runs on test_CT {
444 map(self:GBPVTY, system:GBPVTY);
445 f_vty_set_prompts(GBPVTY);
446 f_vty_transceive(GBPVTY, "enable");
447}
448
Harald Weltefbae83f2020-11-15 23:25:55 +0100449type record of integer ro_integer;
450
451private function ro_integer_contains(ro_integer r, integer x) return boolean {
452 for (var integer j := 0; j < lengthof(r); j := j+1) {
453 if (r[j] == x) {
454 return true;
455 }
456 }
457 return false;
458}
459
Harald Welteb978ed62020-12-12 14:01:11 +0100460private type record of ro_integer roro_integer;
461
462/* count the number of unblocked BVCI for each SGSN NSE */
463private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
464runs on test_CT {
465 var BssgpStatusIndication bsi;
466 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
467 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
468 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
469 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
470 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
471 repeat;
472 }
473 }
474 }
475}
476
Harald Welte425d3762020-12-09 14:33:18 +0100477function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100478 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100479 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200480 var integer i;
481
482 if (g_initialized == true) {
483 return;
484 }
485 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200486
Harald Welte425d3762020-12-09 14:33:18 +0100487 g_Tguard.start(t_guard);
488 activate(as_gTguard(g_Tguard));
489
Harald Welteb978ed62020-12-12 14:01:11 +0100490 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100491 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
492 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100493 /* make sure all have a proper crate_cb, which cannot be specified in config file */
494 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100495 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100496 bvcs := bvcs & g_pcu[i].cfg.bvc;
497 }
498
499 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
500 g_sgsn[i].cfg := {
501 nsei := mp_nsconfig_sgsn[i].nsei,
502 sgsn_role := true,
503 bvc := bvcs
504 }
Harald Welte6d63f742020-11-15 19:44:04 +0100505 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200506
507 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100508 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100509 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100510 }
511 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
512 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
513 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
514 }
515
516 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100517 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100518 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200519 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100520 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100521 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100522 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100523
Harald Welteb978ed62020-12-12 14:01:11 +0100524 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
525 bvci_unblocked[i] := {};
526 }
527
Harald Weltefbae83f2020-11-15 23:25:55 +0100528 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100529 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100530 T.start;
531 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100532 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
533 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
534 [] as_count_unblocked4nse(0, bvci_unblocked);
535 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100536 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
537 repeat;
538 }
Harald Welte3c905152020-11-26 20:56:09 +0100539 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
540 repeat;
541 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100542 [] SGSN_MGMT.receive {
543 setverdict(fail, "Received unexpected message on SGSN_MGMT");
544 mtc.stop;
545 }
546
547 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
548 repeat;
549 }
550 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
551 repeat;
552 }
553 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
554 repeat;
555 }
556 [] PCU_MGMT.receive {
557 setverdict(fail, "Received unexpected message on PCU_MGMT");
558 mtc.stop;
559 }
560
561 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100562 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100563 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100564 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100565 }
566 }
567
Harald Welteb978ed62020-12-12 14:01:11 +0100568 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
569 /* iterate over list and check all BVCI */
570 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
571 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
572 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
573 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
574 mtc.stop;
575 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100576 }
577 }
Harald Welte425d3762020-12-09 14:33:18 +0100578
579 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
580 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200581}
582
583function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100584 var integer i;
585
Daniel Willmann491af2a2021-01-08 01:32:51 +0100586 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
587 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
588 * before the component is shutdown and disconnected. */
589 f_sleep(0.2);
590
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100591 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
592 f_destroy_gb(g_sgsn[i]);
593 }
594 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
595 f_destroy_gb(g_pcu[i]);
596 }
597
598 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200599}
600
601type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
602
603/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte2ecbca82021-01-16 11:23:09 +0100604function f_start_handler(void_fn fn, charstring id, integer imsi_suffix,
Harald Weltec5f486b2021-01-16 11:07:01 +0100605 float t_guard := 30.0, integer sgsn_idx := 0, integer nri_idx := 0)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200606runs on test_CT return BSSGP_ConnHdlr {
607 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100608 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100609 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200610
611 var BSSGP_ConnHdlrPars pars := {
612 imei := f_gen_imei(imsi_suffix),
613 imsi := f_gen_imsi(imsi_suffix),
614 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100615 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200616 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100617 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200618 tlli_old := omit,
619 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100620 pcu := g_pcu,
621 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100622 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200623 t_guard := t_guard
624 };
625
626 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200627
628 vc_conn.start(f_handler_init(fn, id, pars));
629 return vc_conn;
630}
631
Harald Welte2ecbca82021-01-16 11:23:09 +0100632function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0)
Harald Weltec5f486b2021-01-16 11:07:01 +0100633runs on test_CT
634{
635 var integer sgsn_idx, nri_idx;
636 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
637 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
638 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
639 var BSSGP_ConnHdlr vc_conn;
Harald Welte2ecbca82021-01-16 11:23:09 +0100640 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard,
Harald Weltec5f486b2021-01-16 11:07:01 +0100641 sgsn_idx, nri_idx);
642 /* Idea: we could also run them in parallel ? */
643 vc_conn.done;
644 }
645 }
646}
647
Harald Welte3dd21b32020-11-17 19:21:00 +0100648/* 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 +0100649private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
650runs on BSSGP_ConnHdlr {
651 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100652 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100653 /* unregister + disconnect from old BVC */
654 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100655 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100656 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
657 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
658 }
659 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100660 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100661 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
662 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
663 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
664 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100665 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100666}
667
668/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
669private 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 +0100670 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100671 /* unregister + disconnect from old BVC */
672 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100673 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100674 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
675 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
676 }
677 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100678 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100679 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
680 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
681 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
682 sgsn_ct[port_idx] := bvc_ct;
683}
684
Harald Welte425d3762020-12-09 14:33:18 +0100685private altstep as_gTguard(timer Tguard) {
686 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200687 setverdict(fail, "Tguard timeout");
688 mtc.stop;
689 }
690}
691
692/* first function called in every ConnHdlr */
693private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
694runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100695 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200696 /* do some common stuff like setting up g_pars */
697 g_pars := pars;
698
699 llc := f_llc_create(false);
700
Harald Welte3dd21b32020-11-17 19:21:00 +0100701 /* default connections on PCU side: First BVC of each NSE/PCU */
702 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100703 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100704 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100705
706 /* default connections on SGSN side: First BVC of each NSE/SGSN */
707 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
708 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100709 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200710
711 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100712 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200713
714 /* call the user-supplied test case function */
715 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100716
717 for (i := 0; i < NUM_SGSN; i := i+1) {
718 if (SGSN_PROC[i].checkstate("Connected")) {
719 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
720 }
721 }
722
723 for (i := 0; i < NUM_PCU; i := i+1) {
724 if (PCU_PROC[i].checkstate("Connected")) {
725 f_client_unregister(g_pars.imsi, PCU_PROC[i])
726 }
727 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200728}
729
Harald Welte1e834f32020-11-15 20:02:59 +0100730private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
731runs on BSSGP_ConnHdlr {
732 PT.call(BSSGP_register_client:{imsi, tlli}) {
733 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
734 }
735}
736
737private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
738runs on BSSGP_ConnHdlr {
739 PT.call(BSSGP_unregister_client:{imsi}) {
740 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
741 }
742}
743
Harald Welte22ef5d92020-11-16 13:35:14 +0100744/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
745friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100746 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
747 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100748 var PDU_BSSGP rx;
749 timer T := 1.0;
750
Daniel Willmann4798fd72020-11-24 16:23:29 +0100751 if (use_sig) {
752 PCU_SIG[pcu_idx].send(tx);
753 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100754 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100755 }
756
Harald Welte22ef5d92020-11-16 13:35:14 +0100757 T.start;
758 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100759 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
760 setverdict(pass);
761 }
Harald Welte158becf2020-12-09 12:32:32 +0100762 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100763 setverdict(pass);
764 }
Harald Welte158becf2020-12-09 12:32:32 +0100765 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100766 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100767 mtc.stop;
768 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100769 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100770 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100771 mtc.stop;
772 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100773 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100774 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100775 mtc.stop;
776 }
777 }
778}
779
780/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
781friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100782 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
783 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100784 var PDU_BSSGP rx;
785 timer T := 1.0;
786
Daniel Willmann4798fd72020-11-24 16:23:29 +0100787 if (use_sig) {
788 SGSN_SIG[sgsn_idx].send(tx);
789 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100790 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100791 }
792
Harald Welte22ef5d92020-11-16 13:35:14 +0100793 T.start;
794 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100795 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
796 setverdict(pass);
797 }
Harald Welte158becf2020-12-09 12:32:32 +0100798 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100799 setverdict(pass);
800 }
Harald Welte158becf2020-12-09 12:32:32 +0100801 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100802 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
803 mtc.stop;
804 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100805 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
806 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
807 mtc.stop;
808 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100809 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100810 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100811 mtc.stop;
812 }
813 }
814}
Harald Welte1e834f32020-11-15 20:02:59 +0100815
Harald Welte3807ed12020-11-24 19:05:22 +0100816/***********************************************************************
817 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
818 ***********************************************************************/
819
820type component GlobalTest_CT extends test_CT {
821 port BSSGP_PT G_PCU[NUM_PCU];
822 port BSSGP_PT G_SGSN[NUM_SGSN];
823};
824
Harald Welte299aa482020-12-09 15:10:55 +0100825/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100826private function f_global_init() runs on GlobalTest_CT {
827 var integer i;
828 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
829 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
830 }
831 for (i := 0; i < lengthof(g_pcu); i := i+1) {
832 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
833 }
834}
835
Harald Welte299aa482020-12-09 15:10:55 +0100836/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
837private function f_global_init_ptp() runs on GlobalTest_CT {
838 var integer i;
839 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
840 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
841 }
842 for (i := 0; i < lengthof(g_pcu); i := i+1) {
843 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
844 }
845}
846
Harald Welte3807ed12020-11-24 19:05:22 +0100847/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
848friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
849 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
850 var PDU_BSSGP rx;
851 timer T := 1.0;
852
853 G_PCU[pcu_idx].send(tx);
854 T.start;
855 alt {
856 [] G_SGSN[sgsn_idx].receive(exp_rx) {
857 setverdict(pass);
858 }
859 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
860 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
861 mtc.stop;
862 }
863 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100864 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100865 mtc.stop;
866 }
867 }
868}
869
870/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
871friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
872 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
873 var PDU_BSSGP rx;
874 timer T := 1.0;
875
876 G_SGSN[sgsn_idx].send(tx);
877 T.start;
878 alt {
879 [] G_PCU[pcu_idx].receive(exp_rx) {
880 setverdict(pass);
881 }
882 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
883 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
884 mtc.stop;
885 }
886 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100887 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100888 mtc.stop;
889 }
890 }
891}
892
893
Daniel Willmann423d8f42020-09-08 18:58:22 +0200894/* TODO:
895 * Detach without Attach
896 * SM procedures without attach / RAU
897 * ATTACH / RAU
898 ** with / without authentication
899 ** with / without P-TMSI allocation
900 * re-transmissions of LLC frames
901 * PDP Context activation
902 ** with different GGSN config in SGSN VTY
903 ** with different PDP context type (v4/v6/v46)
904 ** timeout from GGSN
905 ** multiple / secondary PDP context
906 */
907
908private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
909 f_sleep(5.0);
910 setverdict(pass);
911}
912
913testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200914 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100915 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200916 f_cleanup();
917}
918
919friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100920 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200921 timer T := 5.0;
922 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100923 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200924 T.start;
925 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100926 [] 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 +0200927 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
928 }
Harald Welte16357a92020-11-17 18:20:00 +0100929 [] 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 +0200930 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
931 mtc.stop;
932 }
933 [] T.timeout {
934 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
935 mtc.stop;
936 }
937 }
938 return '00'O;
939}
940
941friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100942 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200943 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100944 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 +0200945 T.start;
946 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100947 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
948 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200949 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
950 mtc.stop;
951 }
952 [] T.timeout {
953 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
954 mtc.stop;
955 }
956 }
957}
958
959
Harald Welte92686012020-11-15 21:45:49 +0100960/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
961private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100962 var integer ran_idx := 0;
963 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100964 var integer i;
965
Harald Welte0d5fceb2020-11-29 16:04:07 +0100966 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100967 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100968 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 +0100969 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100970 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 +0100971
Harald Welte0d5fceb2020-11-29 16:04:07 +0100972 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100973 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100974 }
975 setverdict(pass);
976}
977
978testcase TC_ul_unitdata() runs on test_CT
979{
Harald Welte92686012020-11-15 21:45:49 +0100980 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100981 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +0100982 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +0100983 f_cleanup();
984}
985
Harald Welte78d8db92020-11-15 23:27:27 +0100986/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
987private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
988 var integer i;
989
Harald Welte0d5fceb2020-11-29 16:04:07 +0100990 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100991 var octetstring payload := f_rnd_octstring(i);
992 var template (value) PDU_BSSGP pdu_tx :=
993 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
994 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
995 var template (present) PDU_BSSGP pdu_rx :=
996 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
997
Harald Welte0d5fceb2020-11-29 16:04:07 +0100998 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100999 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001000 }
1001 setverdict(pass);
1002}
1003
1004testcase TC_dl_unitdata() runs on test_CT
1005{
Harald Welte78d8db92020-11-15 23:27:27 +01001006 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001007 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001008 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001009 f_cleanup();
1010}
Harald Welte92686012020-11-15 21:45:49 +01001011
Harald Welte6dc2ac42020-11-16 09:16:17 +01001012private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1013 var integer i;
1014
1015 for (i := 0; i < 10; i := i+1) {
1016 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1017 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1018 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1019
Harald Welte22ef5d92020-11-16 13:35:14 +01001020 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001021 }
1022 setverdict(pass);
1023}
1024testcase TC_ra_capability() runs on test_CT
1025{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001026 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001027 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001028 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001029 f_cleanup();
1030}
1031
Daniel Willmannace3ece2020-11-16 19:53:26 +01001032private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1033 var integer i;
1034 var OCT1 tag;
1035 for (i := 0; i < 10; i := i+1) {
1036 tag := int2oct(23 + i, 1);
1037 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1038 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1039 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1040
1041 f_pcu2sgsn(pdu_tx, pdu_rx);
1042
1043 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1044 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1045 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1046
1047 f_sgsn2pcu(pdu_tx, pdu_rx);
1048 }
1049 setverdict(pass);
1050}
1051testcase TC_ra_capability_upd() runs on test_CT
1052{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001053 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001054 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001055 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001056 f_cleanup();
1057}
1058
Daniel Willmann165d6612020-11-19 14:27:29 +01001059private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1060 var integer i;
1061 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1062 for (i := 0; i < 10; i := i+1) {
1063 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1064 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1065 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1066
1067 f_pcu2sgsn(pdu_tx, pdu_rx);
1068 }
1069 setverdict(pass);
1070}
1071testcase TC_radio_status() runs on test_CT
1072{
Daniel Willmann165d6612020-11-19 14:27:29 +01001073 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001074 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001075 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001076 f_cleanup();
1077}
1078
Harald Welte99ed5072021-01-15 20:38:58 +01001079private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1080 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001081runs on GlobalTest_CT
1082{
1083 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001084 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1085 nri_bitlen := mp_nri_bitlength);
1086 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001087 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1088 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1089 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1090 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1091
1092 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1093 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1094 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1095 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1096
1097 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1098 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1099 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1100 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1101
1102 /* These messages are simple passed through so just also test sending NACK */
1103 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1104 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1105 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1106 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1107}
1108
Harald Weltec5c33732021-01-15 21:04:35 +01001109private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1110runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001111 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001112
Daniel Willmannfa67f492020-11-19 15:48:05 +01001113 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001114 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001115 }
1116 setverdict(pass);
1117}
Harald Welte3807ed12020-11-24 19:05:22 +01001118testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001119{
Harald Weltec5c33732021-01-15 21:04:35 +01001120 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001121 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001122 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001123 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1124 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1125 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1126 }
1127 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001128 f_cleanup();
1129}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001130
Harald Welte99ed5072021-01-15 20:38:58 +01001131private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1132 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001133runs on GlobalTest_CT
1134{
1135 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001136 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1137 nri_bitlen := mp_nri_bitlength);
1138 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001139 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1140 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1141 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1142 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1143
1144 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1145 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1146 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1147 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1148
1149 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1150 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1151 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1152 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1153
1154 /* These messages are simple passed through so just also test sending NACK */
1155 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1156 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1157 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1158 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1159}
1160
Harald Weltec5c33732021-01-15 21:04:35 +01001161private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1162runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001163 var integer i;
1164
Daniel Willmann087a33d2020-11-19 15:58:43 +01001165 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001166 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001167 }
1168 setverdict(pass);
1169}
Harald Welte3807ed12020-11-24 19:05:22 +01001170testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001171{
Harald Weltec5c33732021-01-15 21:04:35 +01001172 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001173 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001174 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001175 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1176 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1177 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1178 }
1179 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001180 f_cleanup();
1181}
1182
Harald Weltef8ef0282020-11-18 12:16:59 +01001183/* test the load-sharing between multiple NS-VC on the BSS side */
1184private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1185 var integer i;
1186
1187 for (i := 0; i < 10; i := i+1) {
1188 var octetstring payload := f_rnd_octstring(i);
1189 var template (value) PDU_BSSGP pdu_tx :=
1190 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001191 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001192 }
1193 setverdict(pass);
1194}
Harald Welte09a1ce42021-01-16 11:18:38 +01001195
1196private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001197{
1198 const integer num_ue := 10;
1199 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001200 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1201 * side so we get the raw NsUnitdataIndication and hence observe different
1202 * NSVCI */
1203 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1204 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1205
1206 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1207 * of the NS-VC is ALIVE/UNBLOCKED */
1208 f_sleep(3.0);
1209
1210 /* start parallel components generating DL-UNITDATA from the SGSN side */
1211 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001212 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001213 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001214 }
1215
1216 /* now start counting all the messages that were queued before */
1217 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1218 var ro_integer rx_count := { 0, 0, 0, 0 };
1219 timer T := 2.0;
1220 T.start;
1221 alt {
1222 [] as_NsUdiCount(0, rx_count);
1223 [] as_NsUdiCount(1, rx_count);
1224 [] as_NsUdiCount(2, rx_count);
1225 [] as_NsUdiCount(3, rx_count);
1226 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1227 [] NS.receive(NsStatusIndication:?) { repeat; }
1228 [] NS.receive {
1229 setverdict(fail, "Rx unexpected NS");
1230 mtc.stop;
1231 }
1232 [] T.timeout {
1233 }
1234 }
1235 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1236 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1237 if (rx_count[i] == 0) {
1238 setverdict(fail, "Data not shared over all NSVC");
1239 }
1240 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001241}
1242
1243testcase TC_load_sharing_dl() runs on test_CT_NS
1244{
1245 var integer sgsn_idx, nri_idx;
1246 f_init();
1247 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1248 f_TC_load_sharing_dl(sgsn_idx);
1249 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001250 setverdict(pass);
1251}
1252private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1253 var NsUnitdataIndication udi;
1254 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1255 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1256 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1257 repeat;
1258 }
1259}
1260type component test_CT_NS extends test_CT {
1261 port NS_PT NS;
1262};
1263
1264
Harald Welte0e188242020-11-22 21:46:48 +01001265/***********************************************************************
1266 * PAGING PS procedure
1267 ***********************************************************************/
1268
1269private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1270 boolean use_sig := false)
1271runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1272 var template (value) PDU_BSSGP pdu_tx;
1273 var template (present) PDU_BSSGP pdu_rx;
1274 /* we always specify '0' as BVCI in the templates below, as we override it with
1275 * 'p4' later anyway */
1276 pdu_rx := tr_BSSGP_PS_PAGING(0);
1277 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1278 if (ispresent(g_pars.p_tmsi)) {
1279 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1280 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1281 } else {
1282 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1283 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1284 }
1285 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1286 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1287 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001288 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001289 } else {
1290 SGSN_SIG[sgsn_idx].send(pdu_tx);
1291 }
1292 return pdu_rx;
1293}
1294
1295/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1296 * specified PCU index */
1297private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1298 boolean use_sig := false,integer pcu_idx := 0)
1299runs on BSSGP_ConnHdlr {
1300 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001301 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001302 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1303 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1304 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1305 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1306 timer T := 2.0;
1307 T.start;
1308 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001309 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001310 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001311 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001312 repeat;
1313 }
1314 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1315 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1316 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001317 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001318 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001319 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001320 repeat;
1321 }
Harald Welte158becf2020-12-09 12:32:32 +01001322 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001323 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1324 }
Harald Welte158becf2020-12-09 12:32:32 +01001325 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001326 setverdict(fail, "Paging received on unexpected BVC");
1327 }
1328 [] any from PCU_SIG.receive(exp_rx) {
1329 setverdict(fail, "Paging received on unexpected BVC");
1330 }
Harald Welte158becf2020-12-09 12:32:32 +01001331 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001332 setverdict(fail, "Different Paging than expected received PTP BVC");
1333 }
1334 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1335 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1336 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001337 [not test_done] T.timeout {
1338 setverdict(fail, "Timeout waiting for paging");
1339 }
1340 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001341 }
1342}
1343
Harald Welte7462a592020-11-23 22:07:07 +01001344/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1345private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1346 boolean use_sig := false)
1347runs on BSSGP_ConnHdlr {
1348 var template (present) PDU_BSSGP exp_rx;
1349 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1350 /* Expect paging to propagate to no BSS */
1351 timer T := 2.0;
1352 T.start;
1353 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001354 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001355 setverdict(fail, "Paging received on unexpected BVC");
1356 }
1357 [] any from PCU_SIG.receive(exp_rx) {
1358 setverdict(fail, "Paging received on unexpected BVC");
1359 }
Harald Welte158becf2020-12-09 12:32:32 +01001360 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001361 setverdict(fail, "Different Paging received on PTP BVC");
1362 }
1363 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1364 setverdict(fail, "Different Paging received on SIGNALING BVC");
1365 }
1366 [] T.timeout {
1367 setverdict(pass);
1368 }
1369 }
1370}
1371
Harald Welte0e188242020-11-22 21:46:48 +01001372private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1373{
1374 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1375 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1376 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1377}
1378testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001379 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001380 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001381 f_cleanup();
1382}
1383
1384/* PS-PAGING on PTP-BVC for Location Area */
1385private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1386{
1387 var template (present) PDU_BSSGP exp_rx;
1388 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1389 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1390 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1391}
1392testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001393 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001394 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001395 f_cleanup();
1396}
1397
Harald Welte7462a592020-11-23 22:07:07 +01001398/* PS-PAGING on PTP-BVC for unknown Location Area */
1399private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1400{
1401 var GSM_Types.LocationAreaIdentification unknown_la := {
1402 mcc_mnc := '567F99'H,
1403 lac := 33333
1404 };
1405 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1406 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1407}
1408testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001409 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001410 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001411 f_cleanup();
1412}
1413
Harald Welte0e188242020-11-22 21:46:48 +01001414/* PS-PAGING on PTP-BVC for Routeing Area */
1415private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1416{
1417 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1418 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1419 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1420}
1421testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001422 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001423 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001424 f_cleanup();
1425}
1426
Harald Welte7462a592020-11-23 22:07:07 +01001427/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1428private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1429{
1430 var RoutingAreaIdentification unknown_ra := {
1431 lai := {
1432 mcc_mnc := '567F99'H,
1433 lac := 33333
1434 },
1435 rac := 254
1436 };
1437 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1438 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1439}
1440testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001441 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001442 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001443 f_cleanup();
1444}
1445
Harald Welte0e188242020-11-22 21:46:48 +01001446/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1447private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1448{
1449 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1450 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1451}
1452testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001453 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001454 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001455 f_cleanup();
1456}
1457
Harald Welte7462a592020-11-23 22:07:07 +01001458/* PS-PAGING on PTP-BVC for unknown BVCI */
1459private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1460{
1461 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1462 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1463}
1464testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001465 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001466 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001467 f_cleanup();
1468}
1469
Harald Welte0e188242020-11-22 21:46:48 +01001470/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1471private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1472runs on BSSGP_ConnHdlr {
1473[] PCU_SIG[pcu_idx].receive(exp_rx) {
1474 if (ro_integer_contains(roi, pcu_idx)) {
1475 setverdict(fail, "Received multiple paging on same SIG BVC");
1476 }
1477 roi := roi & { pcu_idx };
1478 repeat;
1479 }
Harald Welte158becf2020-12-09 12:32:32 +01001480[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001481 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1482 }
1483[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1484 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1485 }
Harald Welte158becf2020-12-09 12:32:32 +01001486[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001487 setverdict(fail, "Different Paging than expected received PTP BVC");
1488 }
1489}
1490
1491type record of default ro_default;
1492
1493/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1494private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1495 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1496{
1497 var template (present) PDU_BSSGP exp_rx;
1498 exp_rx := f_send_paging_ps(p4, 0, true);
1499
1500 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1501 var ro_default defaults := {};
1502 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1503 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1504 defaults := defaults & { d };
1505 }
1506 f_sleep(2.0);
1507 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1508 deactivate(defaults[i]);
1509 }
1510 log("Paging received on PCU ", g_roi);
1511
1512 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1513 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1514 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1515 if (exp_on_i and not rx_on_i) {
1516 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1517 }
1518 if (not exp_on_i and rx_on_i) {
1519 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1520 }
1521 }
1522 setverdict(pass);
1523}
1524
1525/* PS-PAGING on SIG-BVC for BSS Area */
1526private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1527{
1528 /* we expect the paging to arrive on all three NSE */
1529 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1530}
1531testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001532 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001533 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001534 f_cleanup();
1535}
1536
1537/* PS-PAGING on SIG-BVC for Location Area */
1538private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1539{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001540 /* The first LAC (13135) is shared by all three NSEs */
1541 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1542 /* Reset state */
1543 g_roi := {};
1544 /* Make LAC (13300) available on pcu index 2 */
1545 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1546 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 +01001547}
1548testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001549 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001550 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001551 f_cleanup();
1552}
1553
Harald Welte7462a592020-11-23 22:07:07 +01001554/* PS-PAGING on SIG-BVC for unknown Location Area */
1555private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1556{
1557 var GSM_Types.LocationAreaIdentification unknown_la := {
1558 mcc_mnc := '567F99'H,
1559 lac := 33333
1560 };
1561 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1562}
1563testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001564 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001565 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001566 f_cleanup();
1567}
1568
Harald Welte0e188242020-11-22 21:46:48 +01001569/* PS-PAGING on SIG-BVC for Routeing Area */
1570private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1571{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001572 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001573 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 +01001574 g_roi := {};
1575 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1576 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1577 g_roi := {};
1578 /* PCU index 2 has two matching BVCs with the RA ID */
1579 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1580 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 +01001581}
1582testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001583 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001584 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001585 f_cleanup();
1586}
1587
Harald Welte7462a592020-11-23 22:07:07 +01001588/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1589private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1590{
1591 var RoutingAreaIdentification unknown_ra := {
1592 lai := {
1593 mcc_mnc := '567F99'H,
1594 lac := 33333
1595 },
1596 rac := 254
1597 };
1598 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1599}
1600testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001601 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001602 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001603 f_cleanup();
1604}
1605
Harald Welte0e188242020-11-22 21:46:48 +01001606/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1607private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1608{
1609 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1610}
1611testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001612 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001613 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001614 f_cleanup();
1615}
1616
Harald Welte7462a592020-11-23 22:07:07 +01001617/* PS-PAGING on SIG-BVC for unknown BVCI */
1618private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1619{
1620 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1621}
1622testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001623 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001624 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001625 f_cleanup();
1626}
1627
1628
Harald Welte0e188242020-11-22 21:46:48 +01001629
1630/***********************************************************************
1631 * PAGING CS procedure
1632 ***********************************************************************/
1633
1634private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1635 boolean use_sig := false)
1636runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1637 var template (value) PDU_BSSGP pdu_tx;
1638 var template (present) PDU_BSSGP pdu_rx;
1639 /* we always specify '0' as BVCI in the templates below, as we override it with
1640 * 'p4' later anyway */
1641 pdu_rx := tr_BSSGP_CS_PAGING(0);
1642 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1643 if (ispresent(g_pars.p_tmsi)) {
1644 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1645 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1646 } else {
1647 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1648 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1649 }
1650 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1651 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1652 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001653 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001654 } else {
1655 SGSN_SIG[sgsn_idx].send(pdu_tx);
1656 }
1657 return pdu_rx;
1658}
1659
1660/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1661 * specified PCU index */
1662private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1663 boolean use_sig := false,integer pcu_idx := 0)
1664runs on BSSGP_ConnHdlr {
1665 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001666 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001667 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1668 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1669 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1670 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1671 timer T := 2.0;
1672 T.start;
1673 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001674 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001675 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001676 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001677 repeat;
1678 }
1679 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1680 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1681 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001682 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001683 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001684 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001685 repeat;
1686 }
Harald Welte158becf2020-12-09 12:32:32 +01001687 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001688 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1689 }
Harald Welte158becf2020-12-09 12:32:32 +01001690 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001691 setverdict(fail, "Paging received on unexpected BVC");
1692 }
1693 [] any from PCU_SIG.receive(exp_rx) {
1694 setverdict(fail, "Paging received on unexpected BVC");
1695 }
Harald Welte158becf2020-12-09 12:32:32 +01001696 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001697 setverdict(fail, "Different Paging than expected received PTP BVC");
1698 }
1699 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1700 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1701 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001702 [not test_done] T.timeout {
1703 setverdict(fail, "Timeout while waiting for paging")
1704 }
1705 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001706 }
1707}
1708
Harald Welte7462a592020-11-23 22:07:07 +01001709/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1710private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1711 boolean use_sig := false)
1712runs on BSSGP_ConnHdlr {
1713 var template (present) PDU_BSSGP exp_rx;
1714 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1715 /* Expect paging to propagate to no BSS */
1716 timer T := 2.0;
1717 T.start;
1718 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001719 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001720 setverdict(fail, "Paging received on unexpected BVC");
1721 }
1722 [] any from PCU_SIG.receive(exp_rx) {
1723 setverdict(fail, "Paging received on unexpected BVC");
1724 }
Harald Welte158becf2020-12-09 12:32:32 +01001725 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001726 setverdict(fail, "Different Paging received on PTP BVC");
1727 }
1728 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1729 setverdict(fail, "Different Paging received on SIGNALING BVC");
1730 }
1731 [] T.timeout {
1732 setverdict(pass);
1733 }
1734 }
1735}
1736
Harald Welte0e188242020-11-22 21:46:48 +01001737private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1738{
1739 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1740 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1741 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1742}
1743testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001744 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001745 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01001746 f_cleanup();
1747}
1748
1749/* CS-PAGING on PTP-BVC for Location Area */
1750private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1751{
1752 var template (present) PDU_BSSGP exp_rx;
1753 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1754 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1755 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1756}
1757testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001758 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001759 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01001760 f_cleanup();
1761}
1762
Harald Welte7462a592020-11-23 22:07:07 +01001763/* CS-PAGING on PTP-BVC for unknown Location Area */
1764private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1765{
1766 var GSM_Types.LocationAreaIdentification unknown_la := {
1767 mcc_mnc := '567F99'H,
1768 lac := 33333
1769 };
1770 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1771 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1772}
1773testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001774 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001775 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001776 f_cleanup();
1777}
1778
Harald Welte0e188242020-11-22 21:46:48 +01001779/* CS-PAGING on PTP-BVC for Routeing Area */
1780private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1781{
1782 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1783 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1784 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1785}
1786testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001787 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001788 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01001789 f_cleanup();
1790}
1791
Harald Welte7462a592020-11-23 22:07:07 +01001792/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1793private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1794{
1795 var RoutingAreaIdentification unknown_ra := {
1796 lai := {
1797 mcc_mnc := '567F99'H,
1798 lac := 33333
1799 },
1800 rac := 254
1801 };
1802 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1803 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1804}
1805testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001806 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001807 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001808 f_cleanup();
1809}
1810
Harald Welte0e188242020-11-22 21:46:48 +01001811/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1812private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1813{
1814 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1815 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1816}
1817testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001818 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001819 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01001820 f_cleanup();
1821}
1822
Harald Welte7462a592020-11-23 22:07:07 +01001823/* CS-PAGING on PTP-BVC for unknown BVCI */
1824private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1825{
1826 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1827 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1828}
1829testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001830 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001831 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001832 f_cleanup();
1833}
1834
Harald Welte0e188242020-11-22 21:46:48 +01001835/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1836private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1837 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1838{
1839 var template (present) PDU_BSSGP exp_rx;
1840 exp_rx := f_send_paging_cs(p4, 0, true);
1841
1842 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1843 var ro_default defaults := {};
1844 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1845 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1846 defaults := defaults & { d };
1847 }
1848 f_sleep(2.0);
1849 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1850 deactivate(defaults[i]);
1851 }
1852 log("Paging received on PCU ", g_roi);
1853
1854 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1855 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1856 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1857 if (exp_on_i and not rx_on_i) {
1858 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1859 }
1860 if (not exp_on_i and rx_on_i) {
1861 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1862 }
1863 }
1864 setverdict(pass);
1865}
1866
1867/* CS-PAGING on SIG-BVC for BSS Area */
1868private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1869{
1870 /* we expect the paging to arrive on all three NSE */
1871 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1872}
1873testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001874 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001875 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001876 f_cleanup();
1877}
1878
1879/* CS-PAGING on SIG-BVC for Location Area */
1880private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1881{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001882 /* The first LAC (13135) is shared by all three NSEs */
1883 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1884 /* Reset state */
1885 g_roi := {};
1886 /* Make LAC (13300) available on pcu index 2 */
1887 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1888 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 +01001889}
1890testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001891 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001892 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001893 f_cleanup();
1894}
1895
Harald Welte7462a592020-11-23 22:07:07 +01001896/* CS-PAGING on SIG-BVC for unknown Location Area */
1897private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1898{
1899 var GSM_Types.LocationAreaIdentification unknown_la := {
1900 mcc_mnc := '567F99'H,
1901 lac := 33333
1902 };
1903 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1904}
1905testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001906 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001907 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001908 f_cleanup();
1909}
1910
Harald Welte0e188242020-11-22 21:46:48 +01001911/* CS-PAGING on SIG-BVC for Routeing Area */
1912private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1913{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001914 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001915 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 +01001916 g_roi := {};
1917 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1918 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1919 g_roi := {};
1920 /* PCU index 2 has two matching BVCs with the RA ID */
1921 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1922 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 +01001923}
1924testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001925 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001926 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001927 f_cleanup();
1928}
1929
Harald Welte7462a592020-11-23 22:07:07 +01001930/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1931private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1932{
1933 var RoutingAreaIdentification unknown_ra := {
1934 lai := {
1935 mcc_mnc := '567F99'H,
1936 lac := 33333
1937 },
1938 rac := 254
1939 };
1940 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1941}
1942testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001943 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001944 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001945 f_cleanup();
1946}
1947
Harald Welte0e188242020-11-22 21:46:48 +01001948/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1949private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1950{
1951 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1952}
1953testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001954 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001955 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001956 f_cleanup();
1957}
1958
Harald Welte7462a592020-11-23 22:07:07 +01001959/* CS-PAGING on SIG-BVC for unknown BVCI */
1960private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1961{
1962 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1963}
1964testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001965 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001966 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001967 f_cleanup();
1968}
1969
Harald Welte4f91c3b2020-12-09 12:25:51 +01001970/***********************************************************************
1971 * FLUSH-LL procedure
1972 ***********************************************************************/
1973
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001974private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1975 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1976 var integer i;
1977 for (i := 0; i < 10; i := i+1) {
1978 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1979 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1980 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1981
1982 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1983
1984 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1985 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1986 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1987
1988 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1989 }
1990 setverdict(pass);
1991}
1992testcase TC_flush_ll() runs on test_CT
1993{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001994 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001995 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001996 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001997 f_cleanup();
1998}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001999
Harald Welte4f91c3b2020-12-09 12:25:51 +01002000/***********************************************************************
2001 * SGSN-INVOKE-TRACE procedure
2002 ***********************************************************************/
2003
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002004private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2005runs on GlobalTest_CT {
2006[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2007 if (ro_integer_contains(roi, pcu_idx)) {
2008 setverdict(fail, "Received multiple on same SIG BVC");
2009 }
2010 roi := roi & { pcu_idx };
2011 repeat;
2012 }
2013}
2014/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2015testcase TC_trace() runs on GlobalTest_CT
2016{
2017 var BSSGP_ConnHdlr vc_conn;
2018 f_init();
2019 f_global_init();
2020
2021 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2022 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2023
2024 var ro_default defaults := {};
2025 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2026 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2027 }
2028 G_SGSN[0].send(pdu_tx);
2029 f_sleep(2.0);
2030 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2031 deactivate(defaults[i]);
2032 }
2033
2034 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2035 if (not ro_integer_contains(g_roi, i)) {
2036 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2037 }
2038 }
2039 setverdict(pass);
2040
2041 f_cleanup();
2042}
2043
Harald Welte4f91c3b2020-12-09 12:25:51 +01002044/***********************************************************************
2045 * LLC-DISCARDED procedure
2046 ***********************************************************************/
2047
Harald Weltec0351d12020-11-27 22:49:02 +01002048private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2049 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2050
2051 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2053 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2054
2055 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2056
2057 setverdict(pass);
2058}
2059/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2060testcase TC_llc_discarded() runs on test_CT
2061{
Harald Weltec0351d12020-11-27 22:49:02 +01002062 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002063 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002064 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002065 f_cleanup();
2066}
2067
Harald Welte4f91c3b2020-12-09 12:25:51 +01002068/***********************************************************************
2069 * OVERLOAD procedure
2070 ***********************************************************************/
2071
Harald Weltef20af412020-11-28 16:11:11 +01002072/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2073testcase TC_overload() runs on GlobalTest_CT
2074{
2075 f_init();
2076 f_global_init();
2077
2078 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2079 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2080
2081 var ro_default defaults := {};
2082 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2083 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2084 }
2085 G_SGSN[0].send(pdu_tx);
2086 f_sleep(2.0);
2087 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2088 deactivate(defaults[i]);
2089 }
2090
2091 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2092 if (not ro_integer_contains(g_roi, i)) {
2093 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2094 }
2095 }
2096 setverdict(pass);
2097
2098 f_cleanup();
2099}
2100
Harald Welte4f91c3b2020-12-09 12:25:51 +01002101/***********************************************************************
2102 * BVC-BLOCK / BVC-UNBLOCK procedure
2103 ***********************************************************************/
2104
Harald Welte239aa502020-11-24 23:14:20 +01002105private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2106{
2107 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2108 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2109 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2110
2111 SGSN_MGMT.clear;
2112 PCU_MGMT.clear;
2113
2114 /* block the PTP BVC from the PCU side */
2115 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2116 /* expect state on both PCU and SGSN side to change */
2117 interleave {
2118 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2119 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2120 }
2121 setverdict(pass);
2122}
2123testcase TC_bvc_block_ptp() runs on test_CT
2124{
2125 f_init();
2126 f_sleep(1.0);
2127 f_block_ptp_bvc_from_pcu(0, 0);
2128 f_cleanup();
2129}
2130
2131private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2132{
2133 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2134 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2135 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2136
2137 SGSN_MGMT.clear;
2138 PCU_MGMT.clear;
2139
2140 /* block the PTP BVC from the PCU side */
2141 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2142 /* expect state on both PCU and SGSN side to change */
2143 interleave {
2144 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2145 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2146 }
2147 setverdict(pass);
2148}
2149testcase TC_bvc_unblock_ptp() runs on test_CT
2150{
2151 f_init();
2152 f_sleep(1.0);
2153 f_block_ptp_bvc_from_pcu(0, 0);
2154 f_sleep(1.0);
2155 f_unblock_ptp_bvc_from_pcu(0, 0);
2156 f_cleanup();
2157}
2158
Harald Welte4f91c3b2020-12-09 12:25:51 +01002159/***********************************************************************
2160 * BVC-RESET procedure
2161 ***********************************************************************/
2162
Harald Welte60a8ec72020-11-25 17:12:53 +01002163private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2164[] pt.receive(BssgpStatusIndication:?) { repeat; }
2165}
2166private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2167 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2168 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2169 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2170 }
2171 }
2172 return null;
2173}
2174private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2175{
2176 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2177 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2178 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2179 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2180 var default d;
2181
2182 SGSN_MGMT.clear;
2183 PCU_MGMT.clear;
2184
2185 /* block the PTP BVC from the PCU side */
2186 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2187 /* expect state on both PCU and SGSN side to change */
2188 d := activate(as_ignore_status(SGSN_MGMT));
2189 interleave {
2190 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2191 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2192 }
2193 deactivate(d);
2194 setverdict(pass);
2195}
2196/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2197testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2198{
2199 f_init();
2200 f_sleep(3.0);
2201 f_reset_ptp_bvc_from_pcu(0, 0);
2202 f_cleanup();
2203}
2204
Harald Welte16786e92020-11-27 19:11:56 +01002205private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2206runs on test_CT {
2207 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2208 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2209 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002210 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002211 }
2212}
2213/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2214testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2215
2216 f_init();
2217 f_sleep(3.0);
2218
2219 /* Start BVC-RESET procedure for BVCI=0 */
2220 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2221
2222 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2223 var ro_default defaults := {};
2224 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2225 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2226 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2227 defaults := defaults & { d };
2228 }
2229
2230 timer T := 3.0;
2231 T.start;
2232 alt {
2233 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2234 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2235 }
2236 [] T.timeout;
2237 }
2238
2239 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2240 deactivate(defaults[i]);
2241 }
2242
2243 /* check if BVC-block was received on all expected BVC */
2244 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2245 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2246 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2247 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2248 }
2249 }
2250
2251 /* check if BVC-block was not received on any unexpected BVC is not required as
2252 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002253 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002254 f_cleanup();
2255}
2256
Harald Welte60a8ec72020-11-25 17:12:53 +01002257private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2258{
2259 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2260 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2261 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2262 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2263 var default d;
2264
2265 SGSN_MGMT.clear;
2266 PCU_MGMT.clear;
2267
2268 /* block the PTP BVC from the PCU side */
2269 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2270 /* expect state on both PCU and SGSN side to change */
2271 d := activate(as_ignore_status(PCU_MGMT));
2272 interleave {
2273 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2274 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2275 }
2276 deactivate(d);
2277 setverdict(pass);
2278}
2279/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2280testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2281{
2282 f_init();
2283 f_sleep(3.0);
2284 f_reset_ptp_bvc_from_sgsn(0, 0);
2285 f_cleanup();
2286}
2287
Daniel Willmannef7015f2021-01-08 00:43:56 +01002288private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2289 [] pt.receive {repeat; }
2290}
2291
Harald Welte16786e92020-11-27 19:11:56 +01002292private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2293runs on test_CT {
2294 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2295 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2296 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002297 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002298 }
2299}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002300
Harald Welte16786e92020-11-27 19:11:56 +01002301/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2302testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2303
2304 f_init();
2305 f_sleep(3.0);
2306
Daniel Willmannef7015f2021-01-08 00:43:56 +01002307 SGSN_MGMT.clear;
2308 PCU_MGMT.clear;
2309
Harald Welte16786e92020-11-27 19:11:56 +01002310 /* Start BVC-RESET procedure for BVCI=0 */
2311 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2312
Daniel Willmannef7015f2021-01-08 00:43:56 +01002313 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2314 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2315 * the port and a different message sits at the front we wait forever and fail the test.
2316 */
2317 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2318
Harald Welte16786e92020-11-27 19:11:56 +01002319 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002320 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2321 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2322 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2323 defaults := defaults & { d };
2324 }
2325
2326 f_sleep(3.0);
2327
2328 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2329 deactivate(defaults[i]);
2330 }
2331
2332 /* check if BVC-block was received on all expected BVC */
2333 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2334 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2335 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2336 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2337 }
2338 }
2339
2340 /* check if BVC-block was not received on any unexpected BVC is not required as
2341 * such a message would basically run into 'no matching clause' */
2342
2343 f_cleanup();
2344}
2345
Harald Welte299aa482020-12-09 15:10:55 +01002346/***********************************************************************
2347 * FLOW-CONTROL-BVC procedure
2348 ***********************************************************************/
2349
2350private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2351 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2352runs on GlobalTest_CT {
2353 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2354 roi := roi & { sgsn_idx };
2355 if (ispresent(tx_reply)) {
2356 G_SGSN[sgsn_idx].send(tx_reply);
2357 }
Harald Welte5fb01742021-01-15 21:07:52 +01002358 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002359 }
2360}
2361/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2362testcase TC_fc_bvc() runs on GlobalTest_CT
2363{
2364 f_init();
2365 f_global_init_ptp();
2366
2367 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2368 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2369 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2370 var template (omit) PDU_BSSGP ack_tx :=
2371 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2372
2373 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2374 G_PCU[0].send(pdu_tx);
2375
2376 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2377 var ro_default defaults := {};
2378 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2379 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2380 defaults := defaults & { d };
2381 }
2382
2383 f_sleep(3.0);
2384
2385 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2386 deactivate(defaults[i]);
2387 }
2388
2389 /* check if BVC-block was received on all expected BVC */
2390 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2391 if (not ro_integer_contains(g_roi, i)) {
2392 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2393 }
2394 }
2395
2396 /* Expect ACK on PCU side */
2397 G_PCU[0].receive(ack_tx);
2398
2399 setverdict(pass);
2400
2401 f_cleanup();
2402}
2403
Harald Weltecc3894b2020-12-09 16:50:12 +01002404/***********************************************************************
2405 * FLOW-CONTROL-MS procedure
2406 ***********************************************************************/
2407
2408private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2409 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2410
2411 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2412 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2413 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2414 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2415
2416 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2417 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2418
2419 setverdict(pass);
2420}
2421/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2422testcase TC_fc_ms() runs on test_CT
2423{
Harald Weltecc3894b2020-12-09 16:50:12 +01002424 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002425 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002426 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002427 f_cleanup();
2428}
2429
2430
Harald Welte299aa482020-12-09 15:10:55 +01002431
Daniel Willmann423d8f42020-09-08 18:58:22 +02002432control {
2433 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002434 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002435 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002436 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002437 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002438 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002439 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002440 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002441 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002442 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002443 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002444 execute( TC_bvc_block_ptp() );
2445 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002446 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002447 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002448 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002449 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002450 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002451 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2452 execute( TC_load_sharing_dl() );
2453 }
Harald Welte0e188242020-11-22 21:46:48 +01002454
2455 /* PAGING-PS over PTP BVC */
2456 execute( TC_paging_ps_ptp_bss() );
2457 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002458 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002459 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002460 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002461 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002462 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002463
2464 /* PAGING-PS over SIG BVC */
2465 execute( TC_paging_ps_sig_bss() );
2466 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002467 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002468 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002469 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002470 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002471 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002472
2473 /* PAGING-CS over PTP BVC */
2474 execute( TC_paging_cs_ptp_bss() );
2475 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002476 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002477 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002478 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002479 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002480 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002481
2482 /* PAGING-CS over SIG BVC */
2483 execute( TC_paging_cs_sig_bss() );
2484 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002485 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002486 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002487 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002488 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002489 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002490
2491
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002492 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002493 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002494 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002495}
2496
2497
2498}