blob: 4b7d246e8a1230fac52c5b936e6caae00b2b6640 [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 Welte6d63f742020-11-15 19:44:04 +0100604function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, 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 Welte77218d02021-01-15 19:59:15 +0100620 pcu := pcu,
621 sgsn := 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 Weltec5f486b2021-01-16 11:07:01 +0100632function f_start_handlers(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn,
633 integer imsi_suffix, float t_guard := 30.0)
634runs on test_CT
635{
636 var integer sgsn_idx, nri_idx;
637 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
638 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
639 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
640 var BSSGP_ConnHdlr vc_conn;
641 vc_conn := f_start_handler(fn, id, pcu, sgsn, extd_imsi_suffix, t_guard,
642 sgsn_idx, nri_idx);
643 /* Idea: we could also run them in parallel ? */
644 vc_conn.done;
645 }
646 }
647}
648
Harald Welte3dd21b32020-11-17 19:21:00 +0100649/* 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 +0100650private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
651runs on BSSGP_ConnHdlr {
652 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100653 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100654 /* unregister + disconnect from old BVC */
655 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100656 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100657 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
658 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
659 }
660 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100661 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100662 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
663 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
664 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
665 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100666 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100667}
668
669/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
670private 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 +0100671 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100672 /* unregister + disconnect from old BVC */
673 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100674 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100675 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
676 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
677 }
678 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100679 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100680 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
681 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
682 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
683 sgsn_ct[port_idx] := bvc_ct;
684}
685
Harald Welte425d3762020-12-09 14:33:18 +0100686private altstep as_gTguard(timer Tguard) {
687 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200688 setverdict(fail, "Tguard timeout");
689 mtc.stop;
690 }
691}
692
693/* first function called in every ConnHdlr */
694private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
695runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100696 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200697 /* do some common stuff like setting up g_pars */
698 g_pars := pars;
699
700 llc := f_llc_create(false);
701
Harald Welte3dd21b32020-11-17 19:21:00 +0100702 /* default connections on PCU side: First BVC of each NSE/PCU */
703 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100704 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100705 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100706
707 /* default connections on SGSN side: First BVC of each NSE/SGSN */
708 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
709 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100710 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200711
712 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100713 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200714
715 /* call the user-supplied test case function */
716 fn.apply(id);
717}
718
Harald Welte1e834f32020-11-15 20:02:59 +0100719private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
720runs on BSSGP_ConnHdlr {
721 PT.call(BSSGP_register_client:{imsi, tlli}) {
722 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
723 }
724}
725
726private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
727runs on BSSGP_ConnHdlr {
728 PT.call(BSSGP_unregister_client:{imsi}) {
729 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
730 }
731}
732
Harald Welte22ef5d92020-11-16 13:35:14 +0100733/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
734friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100735 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
736 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100737 var PDU_BSSGP rx;
738 timer T := 1.0;
739
Daniel Willmann4798fd72020-11-24 16:23:29 +0100740 if (use_sig) {
741 PCU_SIG[pcu_idx].send(tx);
742 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100743 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100744 }
745
Harald Welte22ef5d92020-11-16 13:35:14 +0100746 T.start;
747 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100748 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
749 setverdict(pass);
750 }
Harald Welte158becf2020-12-09 12:32:32 +0100751 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100752 setverdict(pass);
753 }
Harald Welte158becf2020-12-09 12:32:32 +0100754 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100755 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100756 mtc.stop;
757 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100758 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100759 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100760 mtc.stop;
761 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100762 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100763 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100764 mtc.stop;
765 }
766 }
767}
768
769/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
770friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100771 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
772 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100773 var PDU_BSSGP rx;
774 timer T := 1.0;
775
Daniel Willmann4798fd72020-11-24 16:23:29 +0100776 if (use_sig) {
777 SGSN_SIG[sgsn_idx].send(tx);
778 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100779 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100780 }
781
Harald Welte22ef5d92020-11-16 13:35:14 +0100782 T.start;
783 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100784 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
785 setverdict(pass);
786 }
Harald Welte158becf2020-12-09 12:32:32 +0100787 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100788 setverdict(pass);
789 }
Harald Welte158becf2020-12-09 12:32:32 +0100790 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100791 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
792 mtc.stop;
793 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100794 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
795 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
796 mtc.stop;
797 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100798 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100799 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100800 mtc.stop;
801 }
802 }
803}
Harald Welte1e834f32020-11-15 20:02:59 +0100804
Harald Welte3807ed12020-11-24 19:05:22 +0100805/***********************************************************************
806 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
807 ***********************************************************************/
808
809type component GlobalTest_CT extends test_CT {
810 port BSSGP_PT G_PCU[NUM_PCU];
811 port BSSGP_PT G_SGSN[NUM_SGSN];
812};
813
Harald Welte299aa482020-12-09 15:10:55 +0100814/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100815private function f_global_init() runs on GlobalTest_CT {
816 var integer i;
817 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
818 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
819 }
820 for (i := 0; i < lengthof(g_pcu); i := i+1) {
821 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
822 }
823}
824
Harald Welte299aa482020-12-09 15:10:55 +0100825/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
826private function f_global_init_ptp() runs on GlobalTest_CT {
827 var integer i;
828 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
829 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
830 }
831 for (i := 0; i < lengthof(g_pcu); i := i+1) {
832 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
833 }
834}
835
Harald Welte3807ed12020-11-24 19:05:22 +0100836/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
837friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
838 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
839 var PDU_BSSGP rx;
840 timer T := 1.0;
841
842 G_PCU[pcu_idx].send(tx);
843 T.start;
844 alt {
845 [] G_SGSN[sgsn_idx].receive(exp_rx) {
846 setverdict(pass);
847 }
848 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
849 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
850 mtc.stop;
851 }
852 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100853 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100854 mtc.stop;
855 }
856 }
857}
858
859/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
860friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
861 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
862 var PDU_BSSGP rx;
863 timer T := 1.0;
864
865 G_SGSN[sgsn_idx].send(tx);
866 T.start;
867 alt {
868 [] G_PCU[pcu_idx].receive(exp_rx) {
869 setverdict(pass);
870 }
871 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
872 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
873 mtc.stop;
874 }
875 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100876 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100877 mtc.stop;
878 }
879 }
880}
881
882
Daniel Willmann423d8f42020-09-08 18:58:22 +0200883/* TODO:
884 * Detach without Attach
885 * SM procedures without attach / RAU
886 * ATTACH / RAU
887 ** with / without authentication
888 ** with / without P-TMSI allocation
889 * re-transmissions of LLC frames
890 * PDP Context activation
891 ** with different GGSN config in SGSN VTY
892 ** with different PDP context type (v4/v6/v46)
893 ** timeout from GGSN
894 ** multiple / secondary PDP context
895 */
896
897private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
898 f_sleep(5.0);
899 setverdict(pass);
900}
901
902testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200903 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +0100904 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200905 f_cleanup();
906}
907
908friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100909 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200910 timer T := 5.0;
911 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100912 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200913 T.start;
914 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100915 [] 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 +0200916 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
917 }
Harald Welte16357a92020-11-17 18:20:00 +0100918 [] 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 +0200919 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
920 mtc.stop;
921 }
922 [] T.timeout {
923 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
924 mtc.stop;
925 }
926 }
927 return '00'O;
928}
929
930friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100931 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200932 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100933 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 +0200934 T.start;
935 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100936 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
937 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200938 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
939 mtc.stop;
940 }
941 [] T.timeout {
942 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
943 mtc.stop;
944 }
945 }
946}
947
948
Harald Welte92686012020-11-15 21:45:49 +0100949/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
950private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100951 var integer ran_idx := 0;
952 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100953 var integer i;
954
Harald Welte0d5fceb2020-11-29 16:04:07 +0100955 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100956 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100957 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 +0100958 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100959 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 +0100960
Harald Welte0d5fceb2020-11-29 16:04:07 +0100961 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100962 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100963 }
964 setverdict(pass);
965}
966
967testcase TC_ul_unitdata() runs on test_CT
968{
Harald Welte92686012020-11-15 21:45:49 +0100969 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +0100970 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
Harald Welte92686012020-11-15 21:45:49 +0100971 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +0100972 f_cleanup();
973}
974
Harald Welte78d8db92020-11-15 23:27:27 +0100975/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
976private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
977 var integer i;
978
Harald Welte0d5fceb2020-11-29 16:04:07 +0100979 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100980 var octetstring payload := f_rnd_octstring(i);
981 var template (value) PDU_BSSGP pdu_tx :=
982 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
983 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
984 var template (present) PDU_BSSGP pdu_rx :=
985 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
986
Harald Welte0d5fceb2020-11-29 16:04:07 +0100987 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100988 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100989 }
990 setverdict(pass);
991}
992
993testcase TC_dl_unitdata() runs on test_CT
994{
Harald Welte78d8db92020-11-15 23:27:27 +0100995 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +0100996 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
Harald Welte78d8db92020-11-15 23:27:27 +0100997 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +0100998 f_cleanup();
999}
Harald Welte92686012020-11-15 21:45:49 +01001000
Harald Welte6dc2ac42020-11-16 09:16:17 +01001001private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1002 var integer i;
1003
1004 for (i := 0; i < 10; i := i+1) {
1005 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1006 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1007 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1008
Harald Welte22ef5d92020-11-16 13:35:14 +01001009 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001010 }
1011 setverdict(pass);
1012}
1013testcase TC_ra_capability() runs on test_CT
1014{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001015 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001016 f_start_handlers(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001017 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001018 f_cleanup();
1019}
1020
Daniel Willmannace3ece2020-11-16 19:53:26 +01001021private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1022 var integer i;
1023 var OCT1 tag;
1024 for (i := 0; i < 10; i := i+1) {
1025 tag := int2oct(23 + i, 1);
1026 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1027 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1028 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1029
1030 f_pcu2sgsn(pdu_tx, pdu_rx);
1031
1032 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1033 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1034 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1035
1036 f_sgsn2pcu(pdu_tx, pdu_rx);
1037 }
1038 setverdict(pass);
1039}
1040testcase TC_ra_capability_upd() runs on test_CT
1041{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001042 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001043 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001044 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001045 f_cleanup();
1046}
1047
Daniel Willmann165d6612020-11-19 14:27:29 +01001048private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1049 var integer i;
1050 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1051 for (i := 0; i < 10; i := i+1) {
1052 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1053 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1054 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1055
1056 f_pcu2sgsn(pdu_tx, pdu_rx);
1057 }
1058 setverdict(pass);
1059}
1060testcase TC_radio_status() runs on test_CT
1061{
Daniel Willmann165d6612020-11-19 14:27:29 +01001062 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001063 f_start_handlers(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001064 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001065 f_cleanup();
1066}
1067
Harald Welte99ed5072021-01-15 20:38:58 +01001068private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1069 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001070runs on GlobalTest_CT
1071{
1072 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001073 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1074 nri_bitlen := mp_nri_bitlength);
1075 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001076 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1077 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1078 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1079 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1080
1081 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1082 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1083 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1084 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1085
1086 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1087 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1088 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1089 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1090
1091 /* These messages are simple passed through so just also test sending NACK */
1092 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1093 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1094 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1095 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1096}
1097
Harald Weltec5c33732021-01-15 21:04:35 +01001098private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1099runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001100 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001101
Daniel Willmannfa67f492020-11-19 15:48:05 +01001102 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001103 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001104 }
1105 setverdict(pass);
1106}
Harald Welte3807ed12020-11-24 19:05:22 +01001107testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001108{
Harald Weltec5c33732021-01-15 21:04:35 +01001109 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001110 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001111 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001112 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1113 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1114 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1115 }
1116 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001117 f_cleanup();
1118}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001119
Harald Welte99ed5072021-01-15 20:38:58 +01001120private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1121 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001122runs on GlobalTest_CT
1123{
1124 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001125 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1126 nri_bitlen := mp_nri_bitlength);
1127 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001128 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1129 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1130 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1131 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1132
1133 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1134 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1135 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1136 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1137
1138 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1139 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1140 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1141 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1142
1143 /* These messages are simple passed through so just also test sending NACK */
1144 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1145 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1146 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1147 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1148}
1149
Harald Weltec5c33732021-01-15 21:04:35 +01001150private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1151runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001152 var integer i;
1153
Daniel Willmann087a33d2020-11-19 15:58:43 +01001154 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001155 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001156 }
1157 setverdict(pass);
1158}
Harald Welte3807ed12020-11-24 19:05:22 +01001159testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001160{
Harald Weltec5c33732021-01-15 21:04:35 +01001161 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001162 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001163 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001164 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1165 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1166 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1167 }
1168 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001169 f_cleanup();
1170}
1171
Harald Weltef8ef0282020-11-18 12:16:59 +01001172/* test the load-sharing between multiple NS-VC on the BSS side */
1173private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1174 var integer i;
1175
1176 for (i := 0; i < 10; i := i+1) {
1177 var octetstring payload := f_rnd_octstring(i);
1178 var template (value) PDU_BSSGP pdu_tx :=
1179 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001180 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001181 }
1182 setverdict(pass);
1183}
1184testcase TC_load_sharing_dl() runs on test_CT_NS
1185{
1186 const integer num_ue := 10;
1187 var BSSGP_ConnHdlr vc_conn[num_ue];
1188 f_init();
1189
1190 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1191 * side so we get the raw NsUnitdataIndication and hence observe different
1192 * NSVCI */
1193 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1194 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1195
1196 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1197 * of the NS-VC is ALIVE/UNBLOCKED */
1198 f_sleep(3.0);
1199
1200 /* start parallel components generating DL-UNITDATA from the SGSN side */
1201 for (var integer i:= 0; i < num_ue; i := i+1) {
1202 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1203 }
1204
1205 /* now start counting all the messages that were queued before */
1206 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1207 var ro_integer rx_count := { 0, 0, 0, 0 };
1208 timer T := 2.0;
1209 T.start;
1210 alt {
1211 [] as_NsUdiCount(0, rx_count);
1212 [] as_NsUdiCount(1, rx_count);
1213 [] as_NsUdiCount(2, rx_count);
1214 [] as_NsUdiCount(3, rx_count);
1215 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1216 [] NS.receive(NsStatusIndication:?) { repeat; }
1217 [] NS.receive {
1218 setverdict(fail, "Rx unexpected NS");
1219 mtc.stop;
1220 }
1221 [] T.timeout {
1222 }
1223 }
1224 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1225 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1226 if (rx_count[i] == 0) {
1227 setverdict(fail, "Data not shared over all NSVC");
1228 }
1229 }
1230 setverdict(pass);
1231}
1232private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1233 var NsUnitdataIndication udi;
1234 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1235 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1236 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1237 repeat;
1238 }
1239}
1240type component test_CT_NS extends test_CT {
1241 port NS_PT NS;
1242};
1243
1244
Harald Welte0e188242020-11-22 21:46:48 +01001245/***********************************************************************
1246 * PAGING PS procedure
1247 ***********************************************************************/
1248
1249private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1250 boolean use_sig := false)
1251runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1252 var template (value) PDU_BSSGP pdu_tx;
1253 var template (present) PDU_BSSGP pdu_rx;
1254 /* we always specify '0' as BVCI in the templates below, as we override it with
1255 * 'p4' later anyway */
1256 pdu_rx := tr_BSSGP_PS_PAGING(0);
1257 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1258 if (ispresent(g_pars.p_tmsi)) {
1259 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1260 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1261 } else {
1262 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1263 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1264 }
1265 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1266 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1267 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001268 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001269 } else {
1270 SGSN_SIG[sgsn_idx].send(pdu_tx);
1271 }
1272 return pdu_rx;
1273}
1274
1275/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1276 * specified PCU index */
1277private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1278 boolean use_sig := false,integer pcu_idx := 0)
1279runs on BSSGP_ConnHdlr {
1280 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001281 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001282 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1283 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1284 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1285 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1286 timer T := 2.0;
1287 T.start;
1288 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001289 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001290 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001291 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001292 repeat;
1293 }
1294 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1295 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1296 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001297 [use_sig and not test_done] PCU_SIG[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 }
Harald Welte158becf2020-12-09 12:32:32 +01001302 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001303 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1304 }
Harald Welte158becf2020-12-09 12:32:32 +01001305 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001306 setverdict(fail, "Paging received on unexpected BVC");
1307 }
1308 [] any from PCU_SIG.receive(exp_rx) {
1309 setverdict(fail, "Paging received on unexpected BVC");
1310 }
Harald Welte158becf2020-12-09 12:32:32 +01001311 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001312 setverdict(fail, "Different Paging than expected received PTP BVC");
1313 }
1314 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1315 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1316 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001317 [not test_done] T.timeout {
1318 setverdict(fail, "Timeout waiting for paging");
1319 }
1320 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001321 }
1322}
1323
Harald Welte7462a592020-11-23 22:07:07 +01001324/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1325private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1326 boolean use_sig := false)
1327runs on BSSGP_ConnHdlr {
1328 var template (present) PDU_BSSGP exp_rx;
1329 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1330 /* Expect paging to propagate to no BSS */
1331 timer T := 2.0;
1332 T.start;
1333 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001334 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001335 setverdict(fail, "Paging received on unexpected BVC");
1336 }
1337 [] any from PCU_SIG.receive(exp_rx) {
1338 setverdict(fail, "Paging received on unexpected BVC");
1339 }
Harald Welte158becf2020-12-09 12:32:32 +01001340 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001341 setverdict(fail, "Different Paging received on PTP BVC");
1342 }
1343 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1344 setverdict(fail, "Different Paging received on SIGNALING BVC");
1345 }
1346 [] T.timeout {
1347 setverdict(pass);
1348 }
1349 }
1350}
1351
Harald Welte0e188242020-11-22 21:46:48 +01001352private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1353{
1354 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1355 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1356 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1357}
1358testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001359 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001360 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
Harald Welte0e188242020-11-22 21:46:48 +01001361 f_cleanup();
1362}
1363
1364/* PS-PAGING on PTP-BVC for Location Area */
1365private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1366{
1367 var template (present) PDU_BSSGP exp_rx;
1368 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1369 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1370 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1371}
1372testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001373 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001374 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
Harald Welte0e188242020-11-22 21:46:48 +01001375 f_cleanup();
1376}
1377
Harald Welte7462a592020-11-23 22:07:07 +01001378/* PS-PAGING on PTP-BVC for unknown Location Area */
1379private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1380{
1381 var GSM_Types.LocationAreaIdentification unknown_la := {
1382 mcc_mnc := '567F99'H,
1383 lac := 33333
1384 };
1385 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1386 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1387}
1388testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001389 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001390 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001391 f_cleanup();
1392}
1393
Harald Welte0e188242020-11-22 21:46:48 +01001394/* PS-PAGING on PTP-BVC for Routeing Area */
1395private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1396{
1397 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1398 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1399 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1400}
1401testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001402 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001403 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte0e188242020-11-22 21:46:48 +01001404 f_cleanup();
1405}
1406
Harald Welte7462a592020-11-23 22:07:07 +01001407/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1408private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1409{
1410 var RoutingAreaIdentification unknown_ra := {
1411 lai := {
1412 mcc_mnc := '567F99'H,
1413 lac := 33333
1414 },
1415 rac := 254
1416 };
1417 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1418 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1419}
1420testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001421 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001422 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001423 f_cleanup();
1424}
1425
Harald Welte0e188242020-11-22 21:46:48 +01001426/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1427private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1428{
1429 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1430 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1431}
1432testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001433 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001434 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
Harald Welte0e188242020-11-22 21:46:48 +01001435 f_cleanup();
1436}
1437
Harald Welte7462a592020-11-23 22:07:07 +01001438/* PS-PAGING on PTP-BVC for unknown BVCI */
1439private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1440{
1441 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1442 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1443}
1444testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001445 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001446 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001447 f_cleanup();
1448}
1449
Harald Welte0e188242020-11-22 21:46:48 +01001450/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1451private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1452runs on BSSGP_ConnHdlr {
1453[] PCU_SIG[pcu_idx].receive(exp_rx) {
1454 if (ro_integer_contains(roi, pcu_idx)) {
1455 setverdict(fail, "Received multiple paging on same SIG BVC");
1456 }
1457 roi := roi & { pcu_idx };
1458 repeat;
1459 }
Harald Welte158becf2020-12-09 12:32:32 +01001460[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001461 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1462 }
1463[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1464 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1465 }
Harald Welte158becf2020-12-09 12:32:32 +01001466[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001467 setverdict(fail, "Different Paging than expected received PTP BVC");
1468 }
1469}
1470
1471type record of default ro_default;
1472
1473/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1474private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1475 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1476{
1477 var template (present) PDU_BSSGP exp_rx;
1478 exp_rx := f_send_paging_ps(p4, 0, true);
1479
1480 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1481 var ro_default defaults := {};
1482 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1483 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1484 defaults := defaults & { d };
1485 }
1486 f_sleep(2.0);
1487 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1488 deactivate(defaults[i]);
1489 }
1490 log("Paging received on PCU ", g_roi);
1491
1492 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1493 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1494 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1495 if (exp_on_i and not rx_on_i) {
1496 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1497 }
1498 if (not exp_on_i and rx_on_i) {
1499 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1500 }
1501 }
1502 setverdict(pass);
1503}
1504
1505/* PS-PAGING on SIG-BVC for BSS Area */
1506private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1507{
1508 /* we expect the paging to arrive on all three NSE */
1509 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1510}
1511testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001512 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001513 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
Harald Welte0e188242020-11-22 21:46:48 +01001514 f_cleanup();
1515}
1516
1517/* PS-PAGING on SIG-BVC for Location Area */
1518private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1519{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001520 /* The first LAC (13135) is shared by all three NSEs */
1521 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1522 /* Reset state */
1523 g_roi := {};
1524 /* Make LAC (13300) available on pcu index 2 */
1525 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1526 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 +01001527}
1528testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001529 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001530 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
Harald Welte0e188242020-11-22 21:46:48 +01001531 f_cleanup();
1532}
1533
Harald Welte7462a592020-11-23 22:07:07 +01001534/* PS-PAGING on SIG-BVC for unknown Location Area */
1535private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1536{
1537 var GSM_Types.LocationAreaIdentification unknown_la := {
1538 mcc_mnc := '567F99'H,
1539 lac := 33333
1540 };
1541 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1542}
1543testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001544 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001545 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001546 f_cleanup();
1547}
1548
Harald Welte0e188242020-11-22 21:46:48 +01001549/* PS-PAGING on SIG-BVC for Routeing Area */
1550private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1551{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001552 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001553 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 +01001554 g_roi := {};
1555 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1556 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1557 g_roi := {};
1558 /* PCU index 2 has two matching BVCs with the RA ID */
1559 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1560 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 +01001561}
1562testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001563 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001564 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
Harald Welte0e188242020-11-22 21:46:48 +01001565 f_cleanup();
1566}
1567
Harald Welte7462a592020-11-23 22:07:07 +01001568/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1569private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1570{
1571 var RoutingAreaIdentification unknown_ra := {
1572 lai := {
1573 mcc_mnc := '567F99'H,
1574 lac := 33333
1575 },
1576 rac := 254
1577 };
1578 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1579}
1580testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001581 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001582 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001583 f_cleanup();
1584}
1585
Harald Welte0e188242020-11-22 21:46:48 +01001586/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1587private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1588{
1589 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1590}
1591testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001592 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001593 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
Harald Welte0e188242020-11-22 21:46:48 +01001594 f_cleanup();
1595}
1596
Harald Welte7462a592020-11-23 22:07:07 +01001597/* PS-PAGING on SIG-BVC for unknown BVCI */
1598private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1599{
1600 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1601}
1602testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001603 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001604 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001605 f_cleanup();
1606}
1607
1608
Harald Welte0e188242020-11-22 21:46:48 +01001609
1610/***********************************************************************
1611 * PAGING CS procedure
1612 ***********************************************************************/
1613
1614private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1615 boolean use_sig := false)
1616runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1617 var template (value) PDU_BSSGP pdu_tx;
1618 var template (present) PDU_BSSGP pdu_rx;
1619 /* we always specify '0' as BVCI in the templates below, as we override it with
1620 * 'p4' later anyway */
1621 pdu_rx := tr_BSSGP_CS_PAGING(0);
1622 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1623 if (ispresent(g_pars.p_tmsi)) {
1624 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1625 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1626 } else {
1627 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1628 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1629 }
1630 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1631 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1632 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001633 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001634 } else {
1635 SGSN_SIG[sgsn_idx].send(pdu_tx);
1636 }
1637 return pdu_rx;
1638}
1639
1640/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1641 * specified PCU index */
1642private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1643 boolean use_sig := false,integer pcu_idx := 0)
1644runs on BSSGP_ConnHdlr {
1645 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001646 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001647 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1648 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1649 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1650 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1651 timer T := 2.0;
1652 T.start;
1653 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001654 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001655 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001656 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001657 repeat;
1658 }
1659 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1660 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1661 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001662 [use_sig and not test_done] PCU_SIG[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 }
Harald Welte158becf2020-12-09 12:32:32 +01001667 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001668 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1669 }
Harald Welte158becf2020-12-09 12:32:32 +01001670 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001671 setverdict(fail, "Paging received on unexpected BVC");
1672 }
1673 [] any from PCU_SIG.receive(exp_rx) {
1674 setverdict(fail, "Paging received on unexpected BVC");
1675 }
Harald Welte158becf2020-12-09 12:32:32 +01001676 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001677 setverdict(fail, "Different Paging than expected received PTP BVC");
1678 }
1679 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1680 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1681 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001682 [not test_done] T.timeout {
1683 setverdict(fail, "Timeout while waiting for paging")
1684 }
1685 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001686 }
1687}
1688
Harald Welte7462a592020-11-23 22:07:07 +01001689/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1690private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1691 boolean use_sig := false)
1692runs on BSSGP_ConnHdlr {
1693 var template (present) PDU_BSSGP exp_rx;
1694 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1695 /* Expect paging to propagate to no BSS */
1696 timer T := 2.0;
1697 T.start;
1698 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001699 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001700 setverdict(fail, "Paging received on unexpected BVC");
1701 }
1702 [] any from PCU_SIG.receive(exp_rx) {
1703 setverdict(fail, "Paging received on unexpected BVC");
1704 }
Harald Welte158becf2020-12-09 12:32:32 +01001705 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001706 setverdict(fail, "Different Paging received on PTP BVC");
1707 }
1708 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1709 setverdict(fail, "Different Paging received on SIGNALING BVC");
1710 }
1711 [] T.timeout {
1712 setverdict(pass);
1713 }
1714 }
1715}
1716
Harald Welte0e188242020-11-22 21:46:48 +01001717private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1718{
1719 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1720 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1721 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1722}
1723testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001724 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001725 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
Harald Welte0e188242020-11-22 21:46:48 +01001726 f_cleanup();
1727}
1728
1729/* CS-PAGING on PTP-BVC for Location Area */
1730private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1731{
1732 var template (present) PDU_BSSGP exp_rx;
1733 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1734 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1735 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1736}
1737testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001738 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001739 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
Harald Welte0e188242020-11-22 21:46:48 +01001740 f_cleanup();
1741}
1742
Harald Welte7462a592020-11-23 22:07:07 +01001743/* CS-PAGING on PTP-BVC for unknown Location Area */
1744private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1745{
1746 var GSM_Types.LocationAreaIdentification unknown_la := {
1747 mcc_mnc := '567F99'H,
1748 lac := 33333
1749 };
1750 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1751 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1752}
1753testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001754 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001755 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001756 f_cleanup();
1757}
1758
Harald Welte0e188242020-11-22 21:46:48 +01001759/* CS-PAGING on PTP-BVC for Routeing Area */
1760private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1761{
1762 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1763 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1764 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1765}
1766testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001767 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001768 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
Harald Welte0e188242020-11-22 21:46:48 +01001769 f_cleanup();
1770}
1771
Harald Welte7462a592020-11-23 22:07:07 +01001772/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1773private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1774{
1775 var RoutingAreaIdentification unknown_ra := {
1776 lai := {
1777 mcc_mnc := '567F99'H,
1778 lac := 33333
1779 },
1780 rac := 254
1781 };
1782 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1783 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1784}
1785testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001786 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001787 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001788 f_cleanup();
1789}
1790
Harald Welte0e188242020-11-22 21:46:48 +01001791/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1792private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1793{
1794 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1795 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1796}
1797testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001798 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001799 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
Harald Welte0e188242020-11-22 21:46:48 +01001800 f_cleanup();
1801}
1802
Harald Welte7462a592020-11-23 22:07:07 +01001803/* CS-PAGING on PTP-BVC for unknown BVCI */
1804private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1805{
1806 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1807 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1808}
1809testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001810 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001811 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001812 f_cleanup();
1813}
1814
Harald Welte0e188242020-11-22 21:46:48 +01001815/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1816private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1817 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1818{
1819 var template (present) PDU_BSSGP exp_rx;
1820 exp_rx := f_send_paging_cs(p4, 0, true);
1821
1822 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1823 var ro_default defaults := {};
1824 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1825 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1826 defaults := defaults & { d };
1827 }
1828 f_sleep(2.0);
1829 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1830 deactivate(defaults[i]);
1831 }
1832 log("Paging received on PCU ", g_roi);
1833
1834 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1835 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1836 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1837 if (exp_on_i and not rx_on_i) {
1838 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1839 }
1840 if (not exp_on_i and rx_on_i) {
1841 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1842 }
1843 }
1844 setverdict(pass);
1845}
1846
1847/* CS-PAGING on SIG-BVC for BSS Area */
1848private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1849{
1850 /* we expect the paging to arrive on all three NSE */
1851 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1852}
1853testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001854 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001855 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
Harald Welte0e188242020-11-22 21:46:48 +01001856 f_cleanup();
1857}
1858
1859/* CS-PAGING on SIG-BVC for Location Area */
1860private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1861{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001862 /* The first LAC (13135) is shared by all three NSEs */
1863 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1864 /* Reset state */
1865 g_roi := {};
1866 /* Make LAC (13300) available on pcu index 2 */
1867 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1868 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 +01001869}
1870testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001871 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001872 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
Harald Welte0e188242020-11-22 21:46:48 +01001873 f_cleanup();
1874}
1875
Harald Welte7462a592020-11-23 22:07:07 +01001876/* CS-PAGING on SIG-BVC for unknown Location Area */
1877private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1878{
1879 var GSM_Types.LocationAreaIdentification unknown_la := {
1880 mcc_mnc := '567F99'H,
1881 lac := 33333
1882 };
1883 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1884}
1885testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001886 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001887 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001888 f_cleanup();
1889}
1890
Harald Welte0e188242020-11-22 21:46:48 +01001891/* CS-PAGING on SIG-BVC for Routeing Area */
1892private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1893{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001894 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001895 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 +01001896 g_roi := {};
1897 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1898 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1899 g_roi := {};
1900 /* PCU index 2 has two matching BVCs with the RA ID */
1901 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1902 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 +01001903}
1904testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001905 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001906 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
Harald Welte0e188242020-11-22 21:46:48 +01001907 f_cleanup();
1908}
1909
Harald Welte7462a592020-11-23 22:07:07 +01001910/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1911private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1912{
1913 var RoutingAreaIdentification unknown_ra := {
1914 lai := {
1915 mcc_mnc := '567F99'H,
1916 lac := 33333
1917 },
1918 rac := 254
1919 };
1920 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1921}
1922testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001923 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001924 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001925 f_cleanup();
1926}
1927
Harald Welte0e188242020-11-22 21:46:48 +01001928/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1929private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1930{
1931 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1932}
1933testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001934 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001935 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
Harald Welte0e188242020-11-22 21:46:48 +01001936 f_cleanup();
1937}
1938
Harald Welte7462a592020-11-23 22:07:07 +01001939/* CS-PAGING on SIG-BVC for unknown BVCI */
1940private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1941{
1942 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1943}
1944testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001945 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001946 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
Harald Welte7462a592020-11-23 22:07:07 +01001947 f_cleanup();
1948}
1949
Harald Welte4f91c3b2020-12-09 12:25:51 +01001950/***********************************************************************
1951 * FLUSH-LL procedure
1952 ***********************************************************************/
1953
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001954private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1955 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1956 var integer i;
1957 for (i := 0; i < 10; i := i+1) {
1958 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1959 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1960 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1961
1962 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1963
1964 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1965 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1966 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1967
1968 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1969 }
1970 setverdict(pass);
1971}
1972testcase TC_flush_ll() runs on test_CT
1973{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001974 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01001975 f_start_handlers(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001976 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001977 f_cleanup();
1978}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001979
Harald Welte4f91c3b2020-12-09 12:25:51 +01001980/***********************************************************************
1981 * SGSN-INVOKE-TRACE procedure
1982 ***********************************************************************/
1983
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001984private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1985runs on GlobalTest_CT {
1986[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1987 if (ro_integer_contains(roi, pcu_idx)) {
1988 setverdict(fail, "Received multiple on same SIG BVC");
1989 }
1990 roi := roi & { pcu_idx };
1991 repeat;
1992 }
1993}
1994/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1995testcase TC_trace() runs on GlobalTest_CT
1996{
1997 var BSSGP_ConnHdlr vc_conn;
1998 f_init();
1999 f_global_init();
2000
2001 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2002 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2003
2004 var ro_default defaults := {};
2005 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2006 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2007 }
2008 G_SGSN[0].send(pdu_tx);
2009 f_sleep(2.0);
2010 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2011 deactivate(defaults[i]);
2012 }
2013
2014 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2015 if (not ro_integer_contains(g_roi, i)) {
2016 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2017 }
2018 }
2019 setverdict(pass);
2020
2021 f_cleanup();
2022}
2023
Harald Welte4f91c3b2020-12-09 12:25:51 +01002024/***********************************************************************
2025 * LLC-DISCARDED procedure
2026 ***********************************************************************/
2027
Harald Weltec0351d12020-11-27 22:49:02 +01002028private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2029 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2030
2031 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2032 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2033 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2034
2035 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2036
2037 setverdict(pass);
2038}
2039/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2040testcase TC_llc_discarded() runs on test_CT
2041{
Harald Weltec0351d12020-11-27 22:49:02 +01002042 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01002043 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002044 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002045 f_cleanup();
2046}
2047
Harald Welte4f91c3b2020-12-09 12:25:51 +01002048/***********************************************************************
2049 * OVERLOAD procedure
2050 ***********************************************************************/
2051
Harald Weltef20af412020-11-28 16:11:11 +01002052/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2053testcase TC_overload() runs on GlobalTest_CT
2054{
2055 f_init();
2056 f_global_init();
2057
2058 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2059 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2060
2061 var ro_default defaults := {};
2062 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2063 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2064 }
2065 G_SGSN[0].send(pdu_tx);
2066 f_sleep(2.0);
2067 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2068 deactivate(defaults[i]);
2069 }
2070
2071 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2072 if (not ro_integer_contains(g_roi, i)) {
2073 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2074 }
2075 }
2076 setverdict(pass);
2077
2078 f_cleanup();
2079}
2080
Harald Welte4f91c3b2020-12-09 12:25:51 +01002081/***********************************************************************
2082 * BVC-BLOCK / BVC-UNBLOCK procedure
2083 ***********************************************************************/
2084
Harald Welte239aa502020-11-24 23:14:20 +01002085private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2086{
2087 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2088 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2089 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2090
2091 SGSN_MGMT.clear;
2092 PCU_MGMT.clear;
2093
2094 /* block the PTP BVC from the PCU side */
2095 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2096 /* expect state on both PCU and SGSN side to change */
2097 interleave {
2098 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2099 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2100 }
2101 setverdict(pass);
2102}
2103testcase TC_bvc_block_ptp() runs on test_CT
2104{
2105 f_init();
2106 f_sleep(1.0);
2107 f_block_ptp_bvc_from_pcu(0, 0);
2108 f_cleanup();
2109}
2110
2111private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2112{
2113 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2114 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2115 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2116
2117 SGSN_MGMT.clear;
2118 PCU_MGMT.clear;
2119
2120 /* block the PTP BVC from the PCU side */
2121 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2122 /* expect state on both PCU and SGSN side to change */
2123 interleave {
2124 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2125 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2126 }
2127 setverdict(pass);
2128}
2129testcase TC_bvc_unblock_ptp() runs on test_CT
2130{
2131 f_init();
2132 f_sleep(1.0);
2133 f_block_ptp_bvc_from_pcu(0, 0);
2134 f_sleep(1.0);
2135 f_unblock_ptp_bvc_from_pcu(0, 0);
2136 f_cleanup();
2137}
2138
Harald Welte4f91c3b2020-12-09 12:25:51 +01002139/***********************************************************************
2140 * BVC-RESET procedure
2141 ***********************************************************************/
2142
Harald Welte60a8ec72020-11-25 17:12:53 +01002143private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2144[] pt.receive(BssgpStatusIndication:?) { repeat; }
2145}
2146private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2147 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2148 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2149 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2150 }
2151 }
2152 return null;
2153}
2154private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2155{
2156 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2157 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2158 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2159 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2160 var default d;
2161
2162 SGSN_MGMT.clear;
2163 PCU_MGMT.clear;
2164
2165 /* block the PTP BVC from the PCU side */
2166 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2167 /* expect state on both PCU and SGSN side to change */
2168 d := activate(as_ignore_status(SGSN_MGMT));
2169 interleave {
2170 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2171 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2172 }
2173 deactivate(d);
2174 setverdict(pass);
2175}
2176/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2177testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2178{
2179 f_init();
2180 f_sleep(3.0);
2181 f_reset_ptp_bvc_from_pcu(0, 0);
2182 f_cleanup();
2183}
2184
Harald Welte16786e92020-11-27 19:11:56 +01002185private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2186runs on test_CT {
2187 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2188 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2189 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002190 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002191 }
2192}
2193/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2194testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2195
2196 f_init();
2197 f_sleep(3.0);
2198
2199 /* Start BVC-RESET procedure for BVCI=0 */
2200 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2201
2202 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2203 var ro_default defaults := {};
2204 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2205 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2206 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2207 defaults := defaults & { d };
2208 }
2209
2210 timer T := 3.0;
2211 T.start;
2212 alt {
2213 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2214 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2215 }
2216 [] T.timeout;
2217 }
2218
2219 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2220 deactivate(defaults[i]);
2221 }
2222
2223 /* check if BVC-block was received on all expected BVC */
2224 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2225 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2226 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2227 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2228 }
2229 }
2230
2231 /* check if BVC-block was not received on any unexpected BVC is not required as
2232 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002233 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002234 f_cleanup();
2235}
2236
Harald Welte60a8ec72020-11-25 17:12:53 +01002237private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2238{
2239 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2240 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2241 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2242 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2243 var default d;
2244
2245 SGSN_MGMT.clear;
2246 PCU_MGMT.clear;
2247
2248 /* block the PTP BVC from the PCU side */
2249 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2250 /* expect state on both PCU and SGSN side to change */
2251 d := activate(as_ignore_status(PCU_MGMT));
2252 interleave {
2253 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2254 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2255 }
2256 deactivate(d);
2257 setverdict(pass);
2258}
2259/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2260testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2261{
2262 f_init();
2263 f_sleep(3.0);
2264 f_reset_ptp_bvc_from_sgsn(0, 0);
2265 f_cleanup();
2266}
2267
Daniel Willmannef7015f2021-01-08 00:43:56 +01002268private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2269 [] pt.receive {repeat; }
2270}
2271
Harald Welte16786e92020-11-27 19:11:56 +01002272private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2273runs on test_CT {
2274 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2275 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2276 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002277 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002278 }
2279}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002280
Harald Welte16786e92020-11-27 19:11:56 +01002281/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2282testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2283
2284 f_init();
2285 f_sleep(3.0);
2286
Daniel Willmannef7015f2021-01-08 00:43:56 +01002287 SGSN_MGMT.clear;
2288 PCU_MGMT.clear;
2289
Harald Welte16786e92020-11-27 19:11:56 +01002290 /* Start BVC-RESET procedure for BVCI=0 */
2291 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2292
Daniel Willmannef7015f2021-01-08 00:43:56 +01002293 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2294 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2295 * the port and a different message sits at the front we wait forever and fail the test.
2296 */
2297 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2298
Harald Welte16786e92020-11-27 19:11:56 +01002299 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002300 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2301 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2302 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2303 defaults := defaults & { d };
2304 }
2305
2306 f_sleep(3.0);
2307
2308 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2309 deactivate(defaults[i]);
2310 }
2311
2312 /* check if BVC-block was received on all expected BVC */
2313 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2314 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2315 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2316 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2317 }
2318 }
2319
2320 /* check if BVC-block was not received on any unexpected BVC is not required as
2321 * such a message would basically run into 'no matching clause' */
2322
2323 f_cleanup();
2324}
2325
Harald Welte299aa482020-12-09 15:10:55 +01002326/***********************************************************************
2327 * FLOW-CONTROL-BVC procedure
2328 ***********************************************************************/
2329
2330private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2331 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2332runs on GlobalTest_CT {
2333 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2334 roi := roi & { sgsn_idx };
2335 if (ispresent(tx_reply)) {
2336 G_SGSN[sgsn_idx].send(tx_reply);
2337 }
Harald Welte5fb01742021-01-15 21:07:52 +01002338 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002339 }
2340}
2341/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2342testcase TC_fc_bvc() runs on GlobalTest_CT
2343{
2344 f_init();
2345 f_global_init_ptp();
2346
2347 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2348 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2349 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2350 var template (omit) PDU_BSSGP ack_tx :=
2351 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2352
2353 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2354 G_PCU[0].send(pdu_tx);
2355
2356 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2357 var ro_default defaults := {};
2358 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2359 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2360 defaults := defaults & { d };
2361 }
2362
2363 f_sleep(3.0);
2364
2365 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2366 deactivate(defaults[i]);
2367 }
2368
2369 /* check if BVC-block was received on all expected BVC */
2370 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2371 if (not ro_integer_contains(g_roi, i)) {
2372 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2373 }
2374 }
2375
2376 /* Expect ACK on PCU side */
2377 G_PCU[0].receive(ack_tx);
2378
2379 setverdict(pass);
2380
2381 f_cleanup();
2382}
2383
Harald Weltecc3894b2020-12-09 16:50:12 +01002384/***********************************************************************
2385 * FLOW-CONTROL-MS procedure
2386 ***********************************************************************/
2387
2388private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2389 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2390
2391 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2392 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2393 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2394 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2395
2396 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2397 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2398
2399 setverdict(pass);
2400}
2401/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2402testcase TC_fc_ms() runs on test_CT
2403{
Harald Weltecc3894b2020-12-09 16:50:12 +01002404 f_init();
Harald Weltec5f486b2021-01-16 11:07:01 +01002405 f_start_handlers(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002406 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002407 f_cleanup();
2408}
2409
2410
Harald Welte299aa482020-12-09 15:10:55 +01002411
Daniel Willmann423d8f42020-09-08 18:58:22 +02002412control {
2413 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002414 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002415 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002416 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002417 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002418 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002419 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002420 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002421 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002422 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002423 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002424 execute( TC_bvc_block_ptp() );
2425 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002426 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002427 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002428 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002429 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002430 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002431 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2432 execute( TC_load_sharing_dl() );
2433 }
Harald Welte0e188242020-11-22 21:46:48 +01002434
2435 /* PAGING-PS over PTP BVC */
2436 execute( TC_paging_ps_ptp_bss() );
2437 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002438 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002439 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002440 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002441 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002442 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002443
2444 /* PAGING-PS over SIG BVC */
2445 execute( TC_paging_ps_sig_bss() );
2446 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002447 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002448 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002449 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002450 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002451 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002452
2453 /* PAGING-CS over PTP BVC */
2454 execute( TC_paging_cs_ptp_bss() );
2455 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002456 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002457 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002458 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002459 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002460 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002461
2462 /* PAGING-CS over SIG BVC */
2463 execute( TC_paging_cs_sig_bss() );
2464 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002465 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002466 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002467 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002468 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002469 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002470
2471
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002472 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002473 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002474 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002475}
2476
2477
2478}