blob: caf4c661ac9f442f3301e9fb8f602cdd82a443c9 [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);
716}
717
Harald Welte1e834f32020-11-15 20:02:59 +0100718private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
719runs on BSSGP_ConnHdlr {
720 PT.call(BSSGP_register_client:{imsi, tlli}) {
721 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
722 }
723}
724
725private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
726runs on BSSGP_ConnHdlr {
727 PT.call(BSSGP_unregister_client:{imsi}) {
728 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
729 }
730}
731
Harald Welte22ef5d92020-11-16 13:35:14 +0100732/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
733friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100734 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
735 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100736 var PDU_BSSGP rx;
737 timer T := 1.0;
738
Daniel Willmann4798fd72020-11-24 16:23:29 +0100739 if (use_sig) {
740 PCU_SIG[pcu_idx].send(tx);
741 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100742 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100743 }
744
Harald Welte22ef5d92020-11-16 13:35:14 +0100745 T.start;
746 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100747 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
748 setverdict(pass);
749 }
Harald Welte158becf2020-12-09 12:32:32 +0100750 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100751 setverdict(pass);
752 }
Harald Welte158becf2020-12-09 12:32:32 +0100753 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100754 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100755 mtc.stop;
756 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100757 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100758 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100759 mtc.stop;
760 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100761 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100762 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100763 mtc.stop;
764 }
765 }
766}
767
768/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
769friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100770 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
771 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100772 var PDU_BSSGP rx;
773 timer T := 1.0;
774
Daniel Willmann4798fd72020-11-24 16:23:29 +0100775 if (use_sig) {
776 SGSN_SIG[sgsn_idx].send(tx);
777 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100778 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100779 }
780
Harald Welte22ef5d92020-11-16 13:35:14 +0100781 T.start;
782 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100783 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
784 setverdict(pass);
785 }
Harald Welte158becf2020-12-09 12:32:32 +0100786 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100787 setverdict(pass);
788 }
Harald Welte158becf2020-12-09 12:32:32 +0100789 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100790 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
791 mtc.stop;
792 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100793 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
794 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
795 mtc.stop;
796 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100797 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100798 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100799 mtc.stop;
800 }
801 }
802}
Harald Welte1e834f32020-11-15 20:02:59 +0100803
Harald Welte3807ed12020-11-24 19:05:22 +0100804/***********************************************************************
805 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
806 ***********************************************************************/
807
808type component GlobalTest_CT extends test_CT {
809 port BSSGP_PT G_PCU[NUM_PCU];
810 port BSSGP_PT G_SGSN[NUM_SGSN];
811};
812
Harald Welte299aa482020-12-09 15:10:55 +0100813/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100814private function f_global_init() runs on GlobalTest_CT {
815 var integer i;
816 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
817 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
818 }
819 for (i := 0; i < lengthof(g_pcu); i := i+1) {
820 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
821 }
822}
823
Harald Welte299aa482020-12-09 15:10:55 +0100824/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
825private function f_global_init_ptp() runs on GlobalTest_CT {
826 var integer i;
827 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
828 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
829 }
830 for (i := 0; i < lengthof(g_pcu); i := i+1) {
831 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
832 }
833}
834
Harald Welte3807ed12020-11-24 19:05:22 +0100835/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
836friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
837 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
838 var PDU_BSSGP rx;
839 timer T := 1.0;
840
841 G_PCU[pcu_idx].send(tx);
842 T.start;
843 alt {
844 [] G_SGSN[sgsn_idx].receive(exp_rx) {
845 setverdict(pass);
846 }
847 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
848 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
849 mtc.stop;
850 }
851 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100852 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100853 mtc.stop;
854 }
855 }
856}
857
858/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
859friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
860 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
861 var PDU_BSSGP rx;
862 timer T := 1.0;
863
864 G_SGSN[sgsn_idx].send(tx);
865 T.start;
866 alt {
867 [] G_PCU[pcu_idx].receive(exp_rx) {
868 setverdict(pass);
869 }
870 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
871 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
872 mtc.stop;
873 }
874 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100875 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100876 mtc.stop;
877 }
878 }
879}
880
881
Daniel Willmann423d8f42020-09-08 18:58:22 +0200882/* TODO:
883 * Detach without Attach
884 * SM procedures without attach / RAU
885 * ATTACH / RAU
886 ** with / without authentication
887 ** with / without P-TMSI allocation
888 * re-transmissions of LLC frames
889 * PDP Context activation
890 ** with different GGSN config in SGSN VTY
891 ** with different PDP context type (v4/v6/v46)
892 ** timeout from GGSN
893 ** multiple / secondary PDP context
894 */
895
896private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
897 f_sleep(5.0);
898 setverdict(pass);
899}
900
901testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200902 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100903 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200904 f_cleanup();
905}
906
907friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100908 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200909 timer T := 5.0;
910 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100911 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200912 T.start;
913 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100914 [] 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 +0200915 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
916 }
Harald Welte16357a92020-11-17 18:20:00 +0100917 [] 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 +0200918 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
919 mtc.stop;
920 }
921 [] T.timeout {
922 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
923 mtc.stop;
924 }
925 }
926 return '00'O;
927}
928
929friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100930 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200931 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100932 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 +0200933 T.start;
934 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100935 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
936 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200937 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
938 mtc.stop;
939 }
940 [] T.timeout {
941 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
942 mtc.stop;
943 }
944 }
945}
946
947
Harald Welte92686012020-11-15 21:45:49 +0100948/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
949private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100950 var integer ran_idx := 0;
951 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100952 var integer i;
953
Harald Welte0d5fceb2020-11-29 16:04:07 +0100954 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100955 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100956 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 +0100957 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100958 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 +0100959
Harald Welte0d5fceb2020-11-29 16:04:07 +0100960 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100961 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100962 }
963 setverdict(pass);
964}
965
966testcase TC_ul_unitdata() runs on test_CT
967{
Harald Welte92686012020-11-15 21:45:49 +0100968 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100969 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +0100970 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +0100971 f_cleanup();
972}
973
Harald Welte78d8db92020-11-15 23:27:27 +0100974/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
975private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
976 var integer i;
977
Harald Welte0d5fceb2020-11-29 16:04:07 +0100978 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100979 var octetstring payload := f_rnd_octstring(i);
980 var template (value) PDU_BSSGP pdu_tx :=
981 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
982 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
983 var template (present) PDU_BSSGP pdu_rx :=
984 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
985
Harald Welte0d5fceb2020-11-29 16:04:07 +0100986 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100987 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100988 }
989 setverdict(pass);
990}
991
992testcase TC_dl_unitdata() runs on test_CT
993{
Harald Welte78d8db92020-11-15 23:27:27 +0100994 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100995 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +0100996 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +0100997 f_cleanup();
998}
Harald Welte92686012020-11-15 21:45:49 +0100999
Harald Welte6dc2ac42020-11-16 09:16:17 +01001000private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1001 var integer i;
1002
1003 for (i := 0; i < 10; i := i+1) {
1004 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1005 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1006 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1007
Harald Welte22ef5d92020-11-16 13:35:14 +01001008 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001009 }
1010 setverdict(pass);
1011}
1012testcase TC_ra_capability() runs on test_CT
1013{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001014 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001015 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001016 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001017 f_cleanup();
1018}
1019
Daniel Willmannace3ece2020-11-16 19:53:26 +01001020private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1021 var integer i;
1022 var OCT1 tag;
1023 for (i := 0; i < 10; i := i+1) {
1024 tag := int2oct(23 + i, 1);
1025 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1026 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1027 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1028
1029 f_pcu2sgsn(pdu_tx, pdu_rx);
1030
1031 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1032 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1033 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1034
1035 f_sgsn2pcu(pdu_tx, pdu_rx);
1036 }
1037 setverdict(pass);
1038}
1039testcase TC_ra_capability_upd() runs on test_CT
1040{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001041 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001042 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001043 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001044 f_cleanup();
1045}
1046
Daniel Willmann165d6612020-11-19 14:27:29 +01001047private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1048 var integer i;
1049 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1050 for (i := 0; i < 10; i := i+1) {
1051 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1053 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1054
1055 f_pcu2sgsn(pdu_tx, pdu_rx);
1056 }
1057 setverdict(pass);
1058}
1059testcase TC_radio_status() runs on test_CT
1060{
Daniel Willmann165d6612020-11-19 14:27:29 +01001061 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001062 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001063 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001064 f_cleanup();
1065}
1066
Harald Welte99ed5072021-01-15 20:38:58 +01001067private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1068 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001069runs on GlobalTest_CT
1070{
1071 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001072 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1073 nri_bitlen := mp_nri_bitlength);
1074 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001075 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1076 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1077 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1078 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1079
1080 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1081 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1082 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1083 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1084
1085 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1086 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1087 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1088 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1089
1090 /* These messages are simple passed through so just also test sending NACK */
1091 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1092 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1093 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1094 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1095}
1096
Harald Weltec5c33732021-01-15 21:04:35 +01001097private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1098runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001099 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001100
Daniel Willmannfa67f492020-11-19 15:48:05 +01001101 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001102 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001103 }
1104 setverdict(pass);
1105}
Harald Welte3807ed12020-11-24 19:05:22 +01001106testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001107{
Harald Weltec5c33732021-01-15 21:04:35 +01001108 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001109 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001110 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001111 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1112 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1113 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1114 }
1115 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001116 f_cleanup();
1117}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001118
Harald Welte99ed5072021-01-15 20:38:58 +01001119private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1120 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001121runs on GlobalTest_CT
1122{
1123 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001124 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1125 nri_bitlen := mp_nri_bitlength);
1126 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001127 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1128 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1129 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1130 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1131
1132 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1133 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1134 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1135 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1136
1137 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1138 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1139 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1140 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1141
1142 /* These messages are simple passed through so just also test sending NACK */
1143 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1144 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1145 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1146 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1147}
1148
Harald Weltec5c33732021-01-15 21:04:35 +01001149private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1150runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001151 var integer i;
1152
Daniel Willmann087a33d2020-11-19 15:58:43 +01001153 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001154 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001155 }
1156 setverdict(pass);
1157}
Harald Welte3807ed12020-11-24 19:05:22 +01001158testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001159{
Harald Weltec5c33732021-01-15 21:04:35 +01001160 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001161 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001162 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001163 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1164 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1165 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1166 }
1167 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001168 f_cleanup();
1169}
1170
Harald Weltef8ef0282020-11-18 12:16:59 +01001171/* test the load-sharing between multiple NS-VC on the BSS side */
1172private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1173 var integer i;
1174
1175 for (i := 0; i < 10; i := i+1) {
1176 var octetstring payload := f_rnd_octstring(i);
1177 var template (value) PDU_BSSGP pdu_tx :=
1178 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001179 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001180 }
1181 setverdict(pass);
1182}
Harald Welte09a1ce42021-01-16 11:18:38 +01001183
1184private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001185{
1186 const integer num_ue := 10;
1187 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001188 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1189 * side so we get the raw NsUnitdataIndication and hence observe different
1190 * NSVCI */
1191 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1192 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1193
1194 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1195 * of the NS-VC is ALIVE/UNBLOCKED */
1196 f_sleep(3.0);
1197
1198 /* start parallel components generating DL-UNITDATA from the SGSN side */
1199 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001200 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001201 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001202 }
1203
1204 /* now start counting all the messages that were queued before */
1205 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1206 var ro_integer rx_count := { 0, 0, 0, 0 };
1207 timer T := 2.0;
1208 T.start;
1209 alt {
1210 [] as_NsUdiCount(0, rx_count);
1211 [] as_NsUdiCount(1, rx_count);
1212 [] as_NsUdiCount(2, rx_count);
1213 [] as_NsUdiCount(3, rx_count);
1214 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1215 [] NS.receive(NsStatusIndication:?) { repeat; }
1216 [] NS.receive {
1217 setverdict(fail, "Rx unexpected NS");
1218 mtc.stop;
1219 }
1220 [] T.timeout {
1221 }
1222 }
1223 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1224 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1225 if (rx_count[i] == 0) {
1226 setverdict(fail, "Data not shared over all NSVC");
1227 }
1228 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001229}
1230
1231testcase TC_load_sharing_dl() runs on test_CT_NS
1232{
1233 var integer sgsn_idx, nri_idx;
1234 f_init();
1235 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1236 f_TC_load_sharing_dl(sgsn_idx);
1237 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001238 setverdict(pass);
1239}
1240private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1241 var NsUnitdataIndication udi;
1242 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1243 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1244 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1245 repeat;
1246 }
1247}
1248type component test_CT_NS extends test_CT {
1249 port NS_PT NS;
1250};
1251
1252
Harald Welte0e188242020-11-22 21:46:48 +01001253/***********************************************************************
1254 * PAGING PS procedure
1255 ***********************************************************************/
1256
1257private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1258 boolean use_sig := false)
1259runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1260 var template (value) PDU_BSSGP pdu_tx;
1261 var template (present) PDU_BSSGP pdu_rx;
1262 /* we always specify '0' as BVCI in the templates below, as we override it with
1263 * 'p4' later anyway */
1264 pdu_rx := tr_BSSGP_PS_PAGING(0);
1265 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1266 if (ispresent(g_pars.p_tmsi)) {
1267 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1268 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1269 } else {
1270 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1271 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1272 }
1273 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1274 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1275 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001276 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001277 } else {
1278 SGSN_SIG[sgsn_idx].send(pdu_tx);
1279 }
1280 return pdu_rx;
1281}
1282
1283/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1284 * specified PCU index */
1285private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1286 boolean use_sig := false,integer pcu_idx := 0)
1287runs on BSSGP_ConnHdlr {
1288 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001289 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001290 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1291 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1292 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1293 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1294 timer T := 2.0;
1295 T.start;
1296 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001297 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001298 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001299 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001300 repeat;
1301 }
1302 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1303 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1304 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001305 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001306 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001307 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001308 repeat;
1309 }
Harald Welte158becf2020-12-09 12:32:32 +01001310 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001311 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1312 }
Harald Welte158becf2020-12-09 12:32:32 +01001313 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001314 setverdict(fail, "Paging received on unexpected BVC");
1315 }
1316 [] any from PCU_SIG.receive(exp_rx) {
1317 setverdict(fail, "Paging received on unexpected BVC");
1318 }
Harald Welte158becf2020-12-09 12:32:32 +01001319 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001320 setverdict(fail, "Different Paging than expected received PTP BVC");
1321 }
1322 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1323 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1324 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001325 [not test_done] T.timeout {
1326 setverdict(fail, "Timeout waiting for paging");
1327 }
1328 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001329 }
1330}
1331
Harald Welte7462a592020-11-23 22:07:07 +01001332/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1333private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1334 boolean use_sig := false)
1335runs on BSSGP_ConnHdlr {
1336 var template (present) PDU_BSSGP exp_rx;
1337 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1338 /* Expect paging to propagate to no BSS */
1339 timer T := 2.0;
1340 T.start;
1341 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001342 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001343 setverdict(fail, "Paging received on unexpected BVC");
1344 }
1345 [] any from PCU_SIG.receive(exp_rx) {
1346 setverdict(fail, "Paging received on unexpected BVC");
1347 }
Harald Welte158becf2020-12-09 12:32:32 +01001348 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001349 setverdict(fail, "Different Paging received on PTP BVC");
1350 }
1351 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1352 setverdict(fail, "Different Paging received on SIGNALING BVC");
1353 }
1354 [] T.timeout {
1355 setverdict(pass);
1356 }
1357 }
1358}
1359
Harald Welte0e188242020-11-22 21:46:48 +01001360private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1361{
1362 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1363 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1364 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1365}
1366testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001367 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001368 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001369 f_cleanup();
1370}
1371
1372/* PS-PAGING on PTP-BVC for Location Area */
1373private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1374{
1375 var template (present) PDU_BSSGP exp_rx;
1376 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1377 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1378 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1379}
1380testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001381 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001382 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001383 f_cleanup();
1384}
1385
Harald Welte7462a592020-11-23 22:07:07 +01001386/* PS-PAGING on PTP-BVC for unknown Location Area */
1387private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1388{
1389 var GSM_Types.LocationAreaIdentification unknown_la := {
1390 mcc_mnc := '567F99'H,
1391 lac := 33333
1392 };
1393 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1394 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1395}
1396testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001397 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001398 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001399 f_cleanup();
1400}
1401
Harald Welte0e188242020-11-22 21:46:48 +01001402/* PS-PAGING on PTP-BVC for Routeing Area */
1403private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1404{
1405 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1406 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1407 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1408}
1409testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001410 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001411 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001412 f_cleanup();
1413}
1414
Harald Welte7462a592020-11-23 22:07:07 +01001415/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1416private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1417{
1418 var RoutingAreaIdentification unknown_ra := {
1419 lai := {
1420 mcc_mnc := '567F99'H,
1421 lac := 33333
1422 },
1423 rac := 254
1424 };
1425 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1426 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1427}
1428testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001429 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001430 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001431 f_cleanup();
1432}
1433
Harald Welte0e188242020-11-22 21:46:48 +01001434/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1435private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1436{
1437 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1438 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1439}
1440testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001441 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001442 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001443 f_cleanup();
1444}
1445
Harald Welte7462a592020-11-23 22:07:07 +01001446/* PS-PAGING on PTP-BVC for unknown BVCI */
1447private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1448{
1449 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1450 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1451}
1452testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001453 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001454 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001455 f_cleanup();
1456}
1457
Harald Welte0e188242020-11-22 21:46:48 +01001458/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1459private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1460runs on BSSGP_ConnHdlr {
1461[] PCU_SIG[pcu_idx].receive(exp_rx) {
1462 if (ro_integer_contains(roi, pcu_idx)) {
1463 setverdict(fail, "Received multiple paging on same SIG BVC");
1464 }
1465 roi := roi & { pcu_idx };
1466 repeat;
1467 }
Harald Welte158becf2020-12-09 12:32:32 +01001468[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001469 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1470 }
1471[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1472 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1473 }
Harald Welte158becf2020-12-09 12:32:32 +01001474[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001475 setverdict(fail, "Different Paging than expected received PTP BVC");
1476 }
1477}
1478
1479type record of default ro_default;
1480
1481/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1482private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1483 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1484{
1485 var template (present) PDU_BSSGP exp_rx;
1486 exp_rx := f_send_paging_ps(p4, 0, true);
1487
1488 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1489 var ro_default defaults := {};
1490 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1491 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1492 defaults := defaults & { d };
1493 }
1494 f_sleep(2.0);
1495 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1496 deactivate(defaults[i]);
1497 }
1498 log("Paging received on PCU ", g_roi);
1499
1500 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1501 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1502 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1503 if (exp_on_i and not rx_on_i) {
1504 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1505 }
1506 if (not exp_on_i and rx_on_i) {
1507 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1508 }
1509 }
1510 setverdict(pass);
1511}
1512
1513/* PS-PAGING on SIG-BVC for BSS Area */
1514private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1515{
1516 /* we expect the paging to arrive on all three NSE */
1517 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1518}
1519testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001520 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001521 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001522 f_cleanup();
1523}
1524
1525/* PS-PAGING on SIG-BVC for Location Area */
1526private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1527{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001528 /* The first LAC (13135) is shared by all three NSEs */
1529 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1530 /* Reset state */
1531 g_roi := {};
1532 /* Make LAC (13300) available on pcu index 2 */
1533 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1534 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 +01001535}
1536testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001537 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001538 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001539 f_cleanup();
1540}
1541
Harald Welte7462a592020-11-23 22:07:07 +01001542/* PS-PAGING on SIG-BVC for unknown Location Area */
1543private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1544{
1545 var GSM_Types.LocationAreaIdentification unknown_la := {
1546 mcc_mnc := '567F99'H,
1547 lac := 33333
1548 };
1549 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1550}
1551testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001552 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001553 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001554 f_cleanup();
1555}
1556
Harald Welte0e188242020-11-22 21:46:48 +01001557/* PS-PAGING on SIG-BVC for Routeing Area */
1558private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1559{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001560 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001561 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 +01001562 g_roi := {};
1563 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1564 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1565 g_roi := {};
1566 /* PCU index 2 has two matching BVCs with the RA ID */
1567 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1568 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 +01001569}
1570testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001571 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001572 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001573 f_cleanup();
1574}
1575
Harald Welte7462a592020-11-23 22:07:07 +01001576/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1577private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1578{
1579 var RoutingAreaIdentification unknown_ra := {
1580 lai := {
1581 mcc_mnc := '567F99'H,
1582 lac := 33333
1583 },
1584 rac := 254
1585 };
1586 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1587}
1588testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001589 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001590 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001591 f_cleanup();
1592}
1593
Harald Welte0e188242020-11-22 21:46:48 +01001594/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1595private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1596{
1597 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1598}
1599testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001600 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001601 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001602 f_cleanup();
1603}
1604
Harald Welte7462a592020-11-23 22:07:07 +01001605/* PS-PAGING on SIG-BVC for unknown BVCI */
1606private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1607{
1608 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1609}
1610testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001611 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001612 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001613 f_cleanup();
1614}
1615
1616
Harald Welte0e188242020-11-22 21:46:48 +01001617
1618/***********************************************************************
1619 * PAGING CS procedure
1620 ***********************************************************************/
1621
1622private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1623 boolean use_sig := false)
1624runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1625 var template (value) PDU_BSSGP pdu_tx;
1626 var template (present) PDU_BSSGP pdu_rx;
1627 /* we always specify '0' as BVCI in the templates below, as we override it with
1628 * 'p4' later anyway */
1629 pdu_rx := tr_BSSGP_CS_PAGING(0);
1630 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1631 if (ispresent(g_pars.p_tmsi)) {
1632 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1633 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1634 } else {
1635 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1636 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1637 }
1638 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1639 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1640 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001641 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001642 } else {
1643 SGSN_SIG[sgsn_idx].send(pdu_tx);
1644 }
1645 return pdu_rx;
1646}
1647
1648/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1649 * specified PCU index */
1650private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1651 boolean use_sig := false,integer pcu_idx := 0)
1652runs on BSSGP_ConnHdlr {
1653 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001654 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001655 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1656 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1657 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1658 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1659 timer T := 2.0;
1660 T.start;
1661 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001662 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001663 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001664 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001665 repeat;
1666 }
1667 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1668 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1669 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001670 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001671 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001672 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001673 repeat;
1674 }
Harald Welte158becf2020-12-09 12:32:32 +01001675 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001676 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1677 }
Harald Welte158becf2020-12-09 12:32:32 +01001678 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001679 setverdict(fail, "Paging received on unexpected BVC");
1680 }
1681 [] any from PCU_SIG.receive(exp_rx) {
1682 setverdict(fail, "Paging received on unexpected BVC");
1683 }
Harald Welte158becf2020-12-09 12:32:32 +01001684 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001685 setverdict(fail, "Different Paging than expected received PTP BVC");
1686 }
1687 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1688 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1689 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001690 [not test_done] T.timeout {
1691 setverdict(fail, "Timeout while waiting for paging")
1692 }
1693 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001694 }
1695}
1696
Harald Welte7462a592020-11-23 22:07:07 +01001697/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1698private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1699 boolean use_sig := false)
1700runs on BSSGP_ConnHdlr {
1701 var template (present) PDU_BSSGP exp_rx;
1702 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1703 /* Expect paging to propagate to no BSS */
1704 timer T := 2.0;
1705 T.start;
1706 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001707 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001708 setverdict(fail, "Paging received on unexpected BVC");
1709 }
1710 [] any from PCU_SIG.receive(exp_rx) {
1711 setverdict(fail, "Paging received on unexpected BVC");
1712 }
Harald Welte158becf2020-12-09 12:32:32 +01001713 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001714 setverdict(fail, "Different Paging received on PTP BVC");
1715 }
1716 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1717 setverdict(fail, "Different Paging received on SIGNALING BVC");
1718 }
1719 [] T.timeout {
1720 setverdict(pass);
1721 }
1722 }
1723}
1724
Harald Welte0e188242020-11-22 21:46:48 +01001725private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1726{
1727 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1728 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1729 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1730}
1731testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001732 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001733 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01001734 f_cleanup();
1735}
1736
1737/* CS-PAGING on PTP-BVC for Location Area */
1738private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1739{
1740 var template (present) PDU_BSSGP exp_rx;
1741 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1742 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1743 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1744}
1745testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001746 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001747 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01001748 f_cleanup();
1749}
1750
Harald Welte7462a592020-11-23 22:07:07 +01001751/* CS-PAGING on PTP-BVC for unknown Location Area */
1752private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1753{
1754 var GSM_Types.LocationAreaIdentification unknown_la := {
1755 mcc_mnc := '567F99'H,
1756 lac := 33333
1757 };
1758 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1759 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1760}
1761testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001762 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001763 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001764 f_cleanup();
1765}
1766
Harald Welte0e188242020-11-22 21:46:48 +01001767/* CS-PAGING on PTP-BVC for Routeing Area */
1768private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1769{
1770 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1771 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1772 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1773}
1774testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001775 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001776 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01001777 f_cleanup();
1778}
1779
Harald Welte7462a592020-11-23 22:07:07 +01001780/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1781private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1782{
1783 var RoutingAreaIdentification unknown_ra := {
1784 lai := {
1785 mcc_mnc := '567F99'H,
1786 lac := 33333
1787 },
1788 rac := 254
1789 };
1790 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1791 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1792}
1793testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001794 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001795 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001796 f_cleanup();
1797}
1798
Harald Welte0e188242020-11-22 21:46:48 +01001799/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1800private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1801{
1802 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1803 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1804}
1805testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001806 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001807 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01001808 f_cleanup();
1809}
1810
Harald Welte7462a592020-11-23 22:07:07 +01001811/* CS-PAGING on PTP-BVC for unknown BVCI */
1812private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1813{
1814 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1815 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1816}
1817testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001818 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001819 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001820 f_cleanup();
1821}
1822
Harald Welte0e188242020-11-22 21:46:48 +01001823/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1824private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1825 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1826{
1827 var template (present) PDU_BSSGP exp_rx;
1828 exp_rx := f_send_paging_cs(p4, 0, true);
1829
1830 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1831 var ro_default defaults := {};
1832 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1833 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1834 defaults := defaults & { d };
1835 }
1836 f_sleep(2.0);
1837 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1838 deactivate(defaults[i]);
1839 }
1840 log("Paging received on PCU ", g_roi);
1841
1842 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1843 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1844 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1845 if (exp_on_i and not rx_on_i) {
1846 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1847 }
1848 if (not exp_on_i and rx_on_i) {
1849 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1850 }
1851 }
1852 setverdict(pass);
1853}
1854
1855/* CS-PAGING on SIG-BVC for BSS Area */
1856private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1857{
1858 /* we expect the paging to arrive on all three NSE */
1859 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1860}
1861testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001862 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001863 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001864 f_cleanup();
1865}
1866
1867/* CS-PAGING on SIG-BVC for Location Area */
1868private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1869{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001870 /* The first LAC (13135) is shared by all three NSEs */
1871 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1872 /* Reset state */
1873 g_roi := {};
1874 /* Make LAC (13300) available on pcu index 2 */
1875 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1876 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 +01001877}
1878testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001879 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001880 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001881 f_cleanup();
1882}
1883
Harald Welte7462a592020-11-23 22:07:07 +01001884/* CS-PAGING on SIG-BVC for unknown Location Area */
1885private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1886{
1887 var GSM_Types.LocationAreaIdentification unknown_la := {
1888 mcc_mnc := '567F99'H,
1889 lac := 33333
1890 };
1891 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1892}
1893testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001894 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001895 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001896 f_cleanup();
1897}
1898
Harald Welte0e188242020-11-22 21:46:48 +01001899/* CS-PAGING on SIG-BVC for Routeing Area */
1900private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1901{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001902 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001903 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 +01001904 g_roi := {};
1905 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1906 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1907 g_roi := {};
1908 /* PCU index 2 has two matching BVCs with the RA ID */
1909 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1910 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 +01001911}
1912testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001913 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001914 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001915 f_cleanup();
1916}
1917
Harald Welte7462a592020-11-23 22:07:07 +01001918/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1919private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1920{
1921 var RoutingAreaIdentification unknown_ra := {
1922 lai := {
1923 mcc_mnc := '567F99'H,
1924 lac := 33333
1925 },
1926 rac := 254
1927 };
1928 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1929}
1930testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001931 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001932 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001933 f_cleanup();
1934}
1935
Harald Welte0e188242020-11-22 21:46:48 +01001936/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1937private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1938{
1939 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1940}
1941testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001942 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001943 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001944 f_cleanup();
1945}
1946
Harald Welte7462a592020-11-23 22:07:07 +01001947/* CS-PAGING on SIG-BVC for unknown BVCI */
1948private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1949{
1950 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1951}
1952testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001953 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001954 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001955 f_cleanup();
1956}
1957
Harald Welte4f91c3b2020-12-09 12:25:51 +01001958/***********************************************************************
1959 * FLUSH-LL procedure
1960 ***********************************************************************/
1961
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001962private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1963 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1964 var integer i;
1965 for (i := 0; i < 10; i := i+1) {
1966 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1967 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1968 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1969
1970 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1971
1972 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1973 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1974 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1975
1976 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1977 }
1978 setverdict(pass);
1979}
1980testcase TC_flush_ll() runs on test_CT
1981{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001982 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001983 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001984 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001985 f_cleanup();
1986}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001987
Harald Welte4f91c3b2020-12-09 12:25:51 +01001988/***********************************************************************
1989 * SGSN-INVOKE-TRACE procedure
1990 ***********************************************************************/
1991
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001992private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1993runs on GlobalTest_CT {
1994[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1995 if (ro_integer_contains(roi, pcu_idx)) {
1996 setverdict(fail, "Received multiple on same SIG BVC");
1997 }
1998 roi := roi & { pcu_idx };
1999 repeat;
2000 }
2001}
2002/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2003testcase TC_trace() runs on GlobalTest_CT
2004{
2005 var BSSGP_ConnHdlr vc_conn;
2006 f_init();
2007 f_global_init();
2008
2009 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2010 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2011
2012 var ro_default defaults := {};
2013 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2014 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2015 }
2016 G_SGSN[0].send(pdu_tx);
2017 f_sleep(2.0);
2018 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2019 deactivate(defaults[i]);
2020 }
2021
2022 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2023 if (not ro_integer_contains(g_roi, i)) {
2024 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2025 }
2026 }
2027 setverdict(pass);
2028
2029 f_cleanup();
2030}
2031
Harald Welte4f91c3b2020-12-09 12:25:51 +01002032/***********************************************************************
2033 * LLC-DISCARDED procedure
2034 ***********************************************************************/
2035
Harald Weltec0351d12020-11-27 22:49:02 +01002036private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2037 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2038
2039 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2040 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2041 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2042
2043 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2044
2045 setverdict(pass);
2046}
2047/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2048testcase TC_llc_discarded() runs on test_CT
2049{
Harald Weltec0351d12020-11-27 22:49:02 +01002050 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002051 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002052 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002053 f_cleanup();
2054}
2055
Harald Welte4f91c3b2020-12-09 12:25:51 +01002056/***********************************************************************
2057 * OVERLOAD procedure
2058 ***********************************************************************/
2059
Harald Weltef20af412020-11-28 16:11:11 +01002060/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2061testcase TC_overload() runs on GlobalTest_CT
2062{
2063 f_init();
2064 f_global_init();
2065
2066 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2067 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2068
2069 var ro_default defaults := {};
2070 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2071 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2072 }
2073 G_SGSN[0].send(pdu_tx);
2074 f_sleep(2.0);
2075 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2076 deactivate(defaults[i]);
2077 }
2078
2079 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2080 if (not ro_integer_contains(g_roi, i)) {
2081 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2082 }
2083 }
2084 setverdict(pass);
2085
2086 f_cleanup();
2087}
2088
Harald Welte4f91c3b2020-12-09 12:25:51 +01002089/***********************************************************************
2090 * BVC-BLOCK / BVC-UNBLOCK procedure
2091 ***********************************************************************/
2092
Harald Welte239aa502020-11-24 23:14:20 +01002093private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2094{
2095 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2096 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2097 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2098
2099 SGSN_MGMT.clear;
2100 PCU_MGMT.clear;
2101
2102 /* block the PTP BVC from the PCU side */
2103 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2104 /* expect state on both PCU and SGSN side to change */
2105 interleave {
2106 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2107 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2108 }
2109 setverdict(pass);
2110}
2111testcase TC_bvc_block_ptp() runs on test_CT
2112{
2113 f_init();
2114 f_sleep(1.0);
2115 f_block_ptp_bvc_from_pcu(0, 0);
2116 f_cleanup();
2117}
2118
2119private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2120{
2121 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2122 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2123 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2124
2125 SGSN_MGMT.clear;
2126 PCU_MGMT.clear;
2127
2128 /* block the PTP BVC from the PCU side */
2129 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2130 /* expect state on both PCU and SGSN side to change */
2131 interleave {
2132 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2133 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2134 }
2135 setverdict(pass);
2136}
2137testcase TC_bvc_unblock_ptp() runs on test_CT
2138{
2139 f_init();
2140 f_sleep(1.0);
2141 f_block_ptp_bvc_from_pcu(0, 0);
2142 f_sleep(1.0);
2143 f_unblock_ptp_bvc_from_pcu(0, 0);
2144 f_cleanup();
2145}
2146
Harald Welte4f91c3b2020-12-09 12:25:51 +01002147/***********************************************************************
2148 * BVC-RESET procedure
2149 ***********************************************************************/
2150
Harald Welte60a8ec72020-11-25 17:12:53 +01002151private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2152[] pt.receive(BssgpStatusIndication:?) { repeat; }
2153}
2154private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2155 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2156 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2157 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2158 }
2159 }
2160 return null;
2161}
2162private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2163{
2164 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2165 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2166 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2167 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2168 var default d;
2169
2170 SGSN_MGMT.clear;
2171 PCU_MGMT.clear;
2172
2173 /* block the PTP BVC from the PCU side */
2174 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2175 /* expect state on both PCU and SGSN side to change */
2176 d := activate(as_ignore_status(SGSN_MGMT));
2177 interleave {
2178 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2179 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2180 }
2181 deactivate(d);
2182 setverdict(pass);
2183}
2184/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2185testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2186{
2187 f_init();
2188 f_sleep(3.0);
2189 f_reset_ptp_bvc_from_pcu(0, 0);
2190 f_cleanup();
2191}
2192
Harald Welte16786e92020-11-27 19:11:56 +01002193private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2194runs on test_CT {
2195 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2196 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2197 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002198 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002199 }
2200}
2201/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2202testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2203
2204 f_init();
2205 f_sleep(3.0);
2206
2207 /* Start BVC-RESET procedure for BVCI=0 */
2208 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2209
2210 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2211 var ro_default defaults := {};
2212 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2213 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2214 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2215 defaults := defaults & { d };
2216 }
2217
2218 timer T := 3.0;
2219 T.start;
2220 alt {
2221 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2222 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2223 }
2224 [] T.timeout;
2225 }
2226
2227 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2228 deactivate(defaults[i]);
2229 }
2230
2231 /* check if BVC-block was received on all expected BVC */
2232 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2233 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2234 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2235 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2236 }
2237 }
2238
2239 /* check if BVC-block was not received on any unexpected BVC is not required as
2240 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002241 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002242 f_cleanup();
2243}
2244
Harald Welte60a8ec72020-11-25 17:12:53 +01002245private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2246{
2247 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2248 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2249 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2250 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2251 var default d;
2252
2253 SGSN_MGMT.clear;
2254 PCU_MGMT.clear;
2255
2256 /* block the PTP BVC from the PCU side */
2257 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2258 /* expect state on both PCU and SGSN side to change */
2259 d := activate(as_ignore_status(PCU_MGMT));
2260 interleave {
2261 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2262 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2263 }
2264 deactivate(d);
2265 setverdict(pass);
2266}
2267/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2268testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2269{
2270 f_init();
2271 f_sleep(3.0);
2272 f_reset_ptp_bvc_from_sgsn(0, 0);
2273 f_cleanup();
2274}
2275
Daniel Willmannef7015f2021-01-08 00:43:56 +01002276private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2277 [] pt.receive {repeat; }
2278}
2279
Harald Welte16786e92020-11-27 19:11:56 +01002280private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2281runs on test_CT {
2282 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2283 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2284 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002285 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002286 }
2287}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002288
Harald Welte16786e92020-11-27 19:11:56 +01002289/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2290testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2291
2292 f_init();
2293 f_sleep(3.0);
2294
Daniel Willmannef7015f2021-01-08 00:43:56 +01002295 SGSN_MGMT.clear;
2296 PCU_MGMT.clear;
2297
Harald Welte16786e92020-11-27 19:11:56 +01002298 /* Start BVC-RESET procedure for BVCI=0 */
2299 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2300
Daniel Willmannef7015f2021-01-08 00:43:56 +01002301 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2302 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2303 * the port and a different message sits at the front we wait forever and fail the test.
2304 */
2305 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2306
Harald Welte16786e92020-11-27 19:11:56 +01002307 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002308 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2309 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2310 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2311 defaults := defaults & { d };
2312 }
2313
2314 f_sleep(3.0);
2315
2316 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2317 deactivate(defaults[i]);
2318 }
2319
2320 /* check if BVC-block was received on all expected BVC */
2321 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2322 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2323 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2324 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2325 }
2326 }
2327
2328 /* check if BVC-block was not received on any unexpected BVC is not required as
2329 * such a message would basically run into 'no matching clause' */
2330
2331 f_cleanup();
2332}
2333
Harald Welte299aa482020-12-09 15:10:55 +01002334/***********************************************************************
2335 * FLOW-CONTROL-BVC procedure
2336 ***********************************************************************/
2337
2338private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2339 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2340runs on GlobalTest_CT {
2341 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2342 roi := roi & { sgsn_idx };
2343 if (ispresent(tx_reply)) {
2344 G_SGSN[sgsn_idx].send(tx_reply);
2345 }
Harald Welte5fb01742021-01-15 21:07:52 +01002346 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002347 }
2348}
2349/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2350testcase TC_fc_bvc() runs on GlobalTest_CT
2351{
2352 f_init();
2353 f_global_init_ptp();
2354
2355 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2356 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2357 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2358 var template (omit) PDU_BSSGP ack_tx :=
2359 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2360
2361 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2362 G_PCU[0].send(pdu_tx);
2363
2364 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2365 var ro_default defaults := {};
2366 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2367 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2368 defaults := defaults & { d };
2369 }
2370
2371 f_sleep(3.0);
2372
2373 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2374 deactivate(defaults[i]);
2375 }
2376
2377 /* check if BVC-block was received on all expected BVC */
2378 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2379 if (not ro_integer_contains(g_roi, i)) {
2380 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2381 }
2382 }
2383
2384 /* Expect ACK on PCU side */
2385 G_PCU[0].receive(ack_tx);
2386
2387 setverdict(pass);
2388
2389 f_cleanup();
2390}
2391
Harald Weltecc3894b2020-12-09 16:50:12 +01002392/***********************************************************************
2393 * FLOW-CONTROL-MS procedure
2394 ***********************************************************************/
2395
2396private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2397 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2398
2399 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2400 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2401 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2402 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2403
2404 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2405 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2406
2407 setverdict(pass);
2408}
2409/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2410testcase TC_fc_ms() runs on test_CT
2411{
Harald Weltecc3894b2020-12-09 16:50:12 +01002412 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002413 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002414 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002415 f_cleanup();
2416}
2417
2418
Harald Welte299aa482020-12-09 15:10:55 +01002419
Daniel Willmann423d8f42020-09-08 18:58:22 +02002420control {
2421 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002422 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002423 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002424 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002425 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002426 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002427 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002428 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002429 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002430 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002431 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002432 execute( TC_bvc_block_ptp() );
2433 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002434 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002435 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002436 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002437 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002438 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002439 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2440 execute( TC_load_sharing_dl() );
2441 }
Harald Welte0e188242020-11-22 21:46:48 +01002442
2443 /* PAGING-PS over PTP BVC */
2444 execute( TC_paging_ps_ptp_bss() );
2445 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002446 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002447 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002448 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002449 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002450 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002451
2452 /* PAGING-PS over SIG BVC */
2453 execute( TC_paging_ps_sig_bss() );
2454 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002455 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002456 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002457 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002458 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002459 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002460
2461 /* PAGING-CS over PTP BVC */
2462 execute( TC_paging_cs_ptp_bss() );
2463 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002464 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002465 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002466 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002467 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002468 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002469
2470 /* PAGING-CS over SIG BVC */
2471 execute( TC_paging_cs_sig_bss() );
2472 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002473 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002474 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002475 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002476 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002477 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002478
2479
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002480 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002481 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002482 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002483}
2484
2485
2486}