blob: 0145c97fff033f5e46ebe1824f767a82bd36124e [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;
17import from GSM_Types all;
18import from Native_Functions all;
19import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
23import from SCCPasp_Types all;
24import from Osmocom_Gb_Types all;
25
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from TELNETasp_PortType all;
33import from Osmocom_VTY_Functions all;
34
35import from LLC_Types all;
36import from LLC_Templates all;
37
38import from GSM_RR_Types all;
39
Harald Welte6d63f742020-11-15 19:44:04 +010040/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
41const BcdMccMnc c_mcc_mnc := '262F42'H;
42
Harald Welte0d5fceb2020-11-29 16:04:07 +010043/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
44const integer max_fr_info_size := 1600;
45
Daniel Willmann423d8f42020-09-08 18:58:22 +020046modulepar {
Harald Weltef6e59b02020-12-08 08:29:09 +010047 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010048 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010049 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020050 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020051 nsei := 101,
52 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010053 handle_sns := false,
54 nsvc := {
55 {
56 provider := {
57 ip := {
58 address_family := AF_INET,
59 local_udp_port := 7777,
60 local_ip := "127.0.0.1",
61 remote_udp_port := 23000,
62 remote_ip := "127.0.0.1"
63 }
64 },
65 nsvci := 101
66 }
67 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020068 }
69 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010070 /* BSS NSEI start at 2000 + x
71 * NSVCI start from value of NSEI + 100
72 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010073 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020074 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010075 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +020076 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010077 handle_sns := false,
78 nsvc := {
79 {
80 provider := {
81 ip := {
82 address_family := AF_INET,
83 local_udp_port := 21010,
84 local_ip := "127.0.0.1",
85 remote_udp_port := 23000,
86 remote_ip := "127.0.0.1"
87 }
88 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +010089 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +010090 }
91 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020092 },
93 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010094 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +020095 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010096 handle_sns := false,
97 nsvc := {
98 {
99 provider := {
100 ip := {
101 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100102 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100103 local_ip := "127.0.0.1",
104 remote_udp_port := 23000,
105 remote_ip := "127.0.0.1"
106 }
107 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100108 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100109 }
110 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200111 },
112 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100113 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200114 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100115 handle_sns := false,
116 nsvc := {
117 {
118 provider := {
119 ip := {
120 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100121 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100122 local_ip := "127.0.0.1",
123 remote_udp_port := 23000,
124 remote_ip := "127.0.0.1"
125 }
126 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100128 }
129 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200130 }
131 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100132 /* BVCI are NSEI*10 + x
133 * The first NSE only has one BVC, the second one 2 and so on
134 * The Cell ID is BVCI + 10000
135 * LAC/RAC are configured in such a way that:
136 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
137 * LAC 13300 is present twice in NSE(2003)
138 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
139 * RAI 13300-0 is present twice in NSE(2003)
140 */
Harald Welte6d63f742020-11-15 19:44:04 +0100141 BssgpConfigs mp_gbconfigs := {
142 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100143 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100144 sgsn_role := false,
145 bvc := {
146 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100147 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100148 cell_id := {
149 ra_id := {
150 lai := {
151 mcc_mnc := c_mcc_mnc,
152 lac := 13135
153 },
154 rac := 0
155 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100156 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100157 },
158 depth := BSSGP_DECODE_DEPTH_BSSGP,
159 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
160 }
161 }
162 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100163 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100164 sgsn_role := false,
165 bvc := {
166 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100167 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100168 cell_id := {
169 ra_id := {
170 lai := {
171 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100172 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100173 },
Harald Welte0e188242020-11-22 21:46:48 +0100174 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100175 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100176 cell_id := 30021
177 },
178 depth := BSSGP_DECODE_DEPTH_BSSGP,
179 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
180 },
181 {
182 bvci := 20022,
183 cell_id := {
184 ra_id := {
185 lai := {
186 mcc_mnc := c_mcc_mnc,
187 lac := 13135
188 },
189 rac := 2
190 },
191 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100192 },
193 depth := BSSGP_DECODE_DEPTH_BSSGP,
194 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
195 }
196 }
197 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100198 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100199 sgsn_role := false,
200 bvc := {
201 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100202 bvci := 20031,
203 cell_id := {
204 ra_id := {
205 lai := {
206 mcc_mnc := c_mcc_mnc,
207 lac := 13135
208 },
209 rac := 1
210 },
211 cell_id := 30031
212 },
213 depth := BSSGP_DECODE_DEPTH_BSSGP,
214 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
215 },
216 {
217 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100218 cell_id := {
219 ra_id := {
220 lai := {
221 mcc_mnc := c_mcc_mnc,
222 lac := 13300
223 },
224 rac := 0
225 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100226 cell_id := 30032
227 },
228 depth := BSSGP_DECODE_DEPTH_BSSGP,
229 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
230 },
231 {
232 bvci := 20033,
233 cell_id := {
234 ra_id := {
235 lai := {
236 mcc_mnc := c_mcc_mnc,
237 lac := 13300
238 },
239 rac := 0
240 },
241 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100242 },
243 depth := BSSGP_DECODE_DEPTH_BSSGP,
244 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
245 }
246 }
247 }
248 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200249};
250
Daniel Willmann423d8f42020-09-08 18:58:22 +0200251type record GbInstance {
252 NS_CT vc_NS,
253 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100254 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200255 BssgpConfig cfg
256};
Harald Welte67dc8c22020-11-17 18:32:29 +0100257type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200258
259const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100260type record of GbInstance GbInstances;
261type record of BssgpConfig BssgpConfigs;
262type record of NSConfiguration NSConfigurations;
263type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200264
265const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200266
267type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100268 var GbInstances g_pcu;
269 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200270
271 port BSSGP_CT_PROC_PT PROC;
272
Harald Weltefbae83f2020-11-15 23:25:55 +0100273 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
274 port BSSGP_BVC_MGMT_PT PCU_MGMT;
275
Daniel Willmann423d8f42020-09-08 18:58:22 +0200276 port TELNETasp_PT GBPVTY;
277
278 var boolean g_initialized := false;
279 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100280
281 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200282};
283
284type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100285 /* array of per-BVC ports on the PCU side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200286 port BSSGP_PT PCU[NUM_PCU];
287 port BSSGP_PT PCU_SIG[NUM_PCU];
288 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100289 /* component reference to the component to which we're currently connected */
290 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100291 /* BSSGP BVC configuration of the component to which we're currently connected */
292 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100293
294 /* array of per-BVC ports on the SGSN side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200295 port BSSGP_PT SGSN[NUM_SGSN];
296 port BSSGP_PT SGSN_SIG[NUM_SGSN];
297 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100298 /* component reference to the component to which we're currently connected */
299 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200300
301 var BSSGP_ConnHdlrPars g_pars;
302 timer g_Tguard;
303 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100304
305 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200306}
307
308type record SGSN_ConnHdlrNetworkPars {
309 boolean expect_ptmsi,
310 boolean expect_auth,
311 boolean expect_ciph
312};
313
314type record BSSGP_ConnHdlrPars {
315 /* IMEI of the simulated ME */
316 hexstring imei,
317 /* IMSI of the simulated MS */
318 hexstring imsi,
319 /* MSISDN of the simulated MS (probably unused) */
320 hexstring msisdn,
321 /* P-TMSI allocated to the simulated MS */
322 OCT4 p_tmsi optional,
323 OCT3 p_tmsi_sig optional,
324 /* TLLI of the simulated MS */
325 OCT4 tlli,
326 OCT4 tlli_old optional,
327 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100328 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100329 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200330 float t_guard
331};
332
333private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
334 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
335 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
336
337 var RoutingAreaIdentificationV ret := {
338 mccDigit1 := mcc_mnc[0],
339 mccDigit2 := mcc_mnc[1],
340 mccDigit3 := mcc_mnc[2],
341 mncDigit3 := mcc_mnc[3],
342 mncDigit1 := mcc_mnc[4],
343 mncDigit2 := mcc_mnc[5],
344 lac := int2oct(cell_id.ra_id.lai.lac, 16),
345 rac := int2oct(cell_id.ra_id.rac, 8)
346 }
347 return ret;
348};
349
Harald Welte95339432020-12-02 18:50:52 +0100350private function f_fix_create_cb(inout BssgpConfig cfg)
351{
352 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
353 if (not isbound(cfg.bvc[i].create_cb)) {
354 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
355 }
356 }
357}
358
Daniel Willmann423d8f42020-09-08 18:58:22 +0200359private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100360 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
361 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
362 gb.vc_NS := NS_CT.create(ns_id);
363 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200364 /* connect lower end of BSSGP emulation with NS upper port */
365 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
366
Harald Welteb419d0e2020-11-16 16:45:05 +0100367 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
368 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200369
370 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
371 connect(self:PROC, gb.vc_BSSGP:PROC);
372 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
373 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100374 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200375 }
Harald Welte16786e92020-11-27 19:11:56 +0100376 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200377}
378
379private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100380 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
381 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
382 gb.vc_NS := NS_CT.create(ns_id);
383 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200384 /* connect lower end of BSSGP emulation with NS upper port */
385 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
386
Harald Welteb419d0e2020-11-16 16:45:05 +0100387 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
388 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200389
390 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
391 connect(self:PROC, gb.vc_BSSGP:PROC);
392 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
393 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100394 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200395 }
Harald Welte16786e92020-11-27 19:11:56 +0100396 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397}
398
399
400private function f_init_vty() runs on test_CT {
401 map(self:GBPVTY, system:GBPVTY);
402 f_vty_set_prompts(GBPVTY);
403 f_vty_transceive(GBPVTY, "enable");
404}
405
Harald Weltefbae83f2020-11-15 23:25:55 +0100406type record of integer ro_integer;
407
408private function ro_integer_contains(ro_integer r, integer x) return boolean {
409 for (var integer j := 0; j < lengthof(r); j := j+1) {
410 if (r[j] == x) {
411 return true;
412 }
413 }
414 return false;
415}
416
Harald Welte6d63f742020-11-15 19:44:04 +0100417function f_init() runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100418 var ro_integer bvci_unblocked := {};
419 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200420 var integer i;
421
422 if (g_initialized == true) {
423 return;
424 }
425 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200426
427 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100428 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200429 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100430 bvc := { }
431 }
432 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
433 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100434 /* make sure all have a proper crate_cb, which cannot be specified in config file */
435 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100436 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welte95339432020-12-02 18:50:52 +0100437 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & g_pcu[i].cfg.bvc;
Harald Welte6d63f742020-11-15 19:44:04 +0100438 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200439
440 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100441 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100442 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100443 }
444 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
445 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
446 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
447 }
448
449 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100450 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100451 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100453 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100454 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100455 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100456
457 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100458 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100459 T.start;
460 alt {
461 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
462 bvci_unblocked := bvci_unblocked & { bsi.bvci };
463 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
464 repeat;
465 }
466 }
467 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
468 repeat;
469 }
Harald Welte3c905152020-11-26 20:56:09 +0100470 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
471 repeat;
472 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100473 [] SGSN_MGMT.receive {
474 setverdict(fail, "Received unexpected message on SGSN_MGMT");
475 mtc.stop;
476 }
477
478 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
479 repeat;
480 }
481 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
482 repeat;
483 }
484 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
485 repeat;
486 }
487 [] PCU_MGMT.receive {
488 setverdict(fail, "Received unexpected message on PCU_MGMT");
489 mtc.stop;
490 }
491
492 [] T.timeout {
493 setverdict(fail, "Timeout waiting for unblock of all BVCs");
494 mtc.stop;
495 }
496 }
497
498 /* iterate over list and check all BVCI */
499 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
500 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
501 if (not ro_integer_contains(bvci_unblocked, bvci)) {
502 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
503 mtc.stop;
504 }
505 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200506}
507
508function f_cleanup() runs on test_CT {
509 self.stop;
510}
511
512type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
513
514/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100515function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200516 float t_guard := 30.0)
517runs on test_CT return BSSGP_ConnHdlr {
518 var BSSGP_ConnHdlr vc_conn;
519
520 var BSSGP_ConnHdlrPars pars := {
521 imei := f_gen_imei(imsi_suffix),
522 imsi := f_gen_imsi(imsi_suffix),
523 msisdn := f_gen_msisdn(imsi_suffix),
524 p_tmsi := omit,
525 p_tmsi_sig := omit,
526 tlli := f_gprs_tlli_random(),
527 tlli_old := omit,
528 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100529 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100530 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200531 t_guard := t_guard
532 };
533
534 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200535
536 vc_conn.start(f_handler_init(fn, id, pars));
537 return vc_conn;
538}
539
Harald Welte3dd21b32020-11-17 19:21:00 +0100540/* 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 +0100541private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
542runs on BSSGP_ConnHdlr {
543 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100544 if (PCU[port_idx].checkstate("Connected")) {
545 /* unregister + disconnect from old BVC */
546 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
547 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
548 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
549 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
550 }
551 /* connect to new BVC and register us */
552 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
553 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
554 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
555 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
556 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100557 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100558}
559
560/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
561private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
562 if (SGSN[port_idx].checkstate("Connected")) {
563 /* unregister + disconnect from old BVC */
564 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
565 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
566 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
567 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
568 }
569 /* connect to new BVC and register us */
570 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
571 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
572 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
573 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
574 sgsn_ct[port_idx] := bvc_ct;
575}
576
Daniel Willmann423d8f42020-09-08 18:58:22 +0200577private altstep as_Tguard() runs on BSSGP_ConnHdlr {
578 [] g_Tguard.timeout {
579 setverdict(fail, "Tguard timeout");
580 mtc.stop;
581 }
582}
583
584/* first function called in every ConnHdlr */
585private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
586runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100587 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200588 /* do some common stuff like setting up g_pars */
589 g_pars := pars;
590
591 llc := f_llc_create(false);
592
Harald Welte3dd21b32020-11-17 19:21:00 +0100593 /* default connections on PCU side: First BVC of each NSE/PCU */
594 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100595 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100596 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100597
598 /* default connections on SGSN side: First BVC of each NSE/SGSN */
599 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
600 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100601 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200602
603 g_Tguard.start(pars.t_guard);
604 activate(as_Tguard());
605
606 /* call the user-supplied test case function */
607 fn.apply(id);
608}
609
Harald Welte1e834f32020-11-15 20:02:59 +0100610private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
611runs on BSSGP_ConnHdlr {
612 PT.call(BSSGP_register_client:{imsi, tlli}) {
613 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
614 }
615}
616
617private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
618runs on BSSGP_ConnHdlr {
619 PT.call(BSSGP_unregister_client:{imsi}) {
620 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
621 }
622}
623
Harald Welte22ef5d92020-11-16 13:35:14 +0100624/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
625friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100626 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100627 var PDU_BSSGP rx;
628 timer T := 1.0;
629
Daniel Willmann4798fd72020-11-24 16:23:29 +0100630 if (use_sig) {
631 PCU_SIG[pcu_idx].send(tx);
632 } else {
633 PCU[pcu_idx].send(tx);
634 }
635
Harald Welte22ef5d92020-11-16 13:35:14 +0100636 T.start;
637 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100638 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
639 setverdict(pass);
640 }
641 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100642 setverdict(pass);
643 }
644 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
645 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
646 mtc.stop;
647 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100648 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
649 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
650 mtc.stop;
651 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100652 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100653 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100654 mtc.stop;
655 }
656 }
657}
658
659/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
660friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100661 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100662 var PDU_BSSGP rx;
663 timer T := 1.0;
664
Daniel Willmann4798fd72020-11-24 16:23:29 +0100665 if (use_sig) {
666 SGSN_SIG[sgsn_idx].send(tx);
667 } else {
668 SGSN[sgsn_idx].send(tx);
669 }
670
Harald Welte22ef5d92020-11-16 13:35:14 +0100671 T.start;
672 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100673 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
674 setverdict(pass);
675 }
676 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100677 setverdict(pass);
678 }
679 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
680 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
681 mtc.stop;
682 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100683 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
684 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
685 mtc.stop;
686 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100687 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100688 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100689 mtc.stop;
690 }
691 }
692}
Harald Welte1e834f32020-11-15 20:02:59 +0100693
Harald Welte3807ed12020-11-24 19:05:22 +0100694/***********************************************************************
695 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
696 ***********************************************************************/
697
698type component GlobalTest_CT extends test_CT {
699 port BSSGP_PT G_PCU[NUM_PCU];
700 port BSSGP_PT G_SGSN[NUM_SGSN];
701};
702
703private function f_global_init() runs on GlobalTest_CT {
704 var integer i;
705 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
706 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
707 }
708 for (i := 0; i < lengthof(g_pcu); i := i+1) {
709 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
710 }
711}
712
713/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
714friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
715 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
716 var PDU_BSSGP rx;
717 timer T := 1.0;
718
719 G_PCU[pcu_idx].send(tx);
720 T.start;
721 alt {
722 [] G_SGSN[sgsn_idx].receive(exp_rx) {
723 setverdict(pass);
724 }
725 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
726 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
727 mtc.stop;
728 }
729 [] T.timeout {
730 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
731 mtc.stop;
732 }
733 }
734}
735
736/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
737friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
738 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
739 var PDU_BSSGP rx;
740 timer T := 1.0;
741
742 G_SGSN[sgsn_idx].send(tx);
743 T.start;
744 alt {
745 [] G_PCU[pcu_idx].receive(exp_rx) {
746 setverdict(pass);
747 }
748 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
749 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
750 mtc.stop;
751 }
752 [] T.timeout {
753 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
754 mtc.stop;
755 }
756 }
757}
758
759
Daniel Willmann423d8f42020-09-08 18:58:22 +0200760/* TODO:
761 * Detach without Attach
762 * SM procedures without attach / RAU
763 * ATTACH / RAU
764 ** with / without authentication
765 ** with / without P-TMSI allocation
766 * re-transmissions of LLC frames
767 * PDP Context activation
768 ** with different GGSN config in SGSN VTY
769 ** with different PDP context type (v4/v6/v46)
770 ** timeout from GGSN
771 ** multiple / secondary PDP context
772 */
773
774private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
775 f_sleep(5.0);
776 setverdict(pass);
777}
778
779testcase TC_BVC_bringup() runs on test_CT {
780 var BSSGP_ConnHdlr vc_conn;
781 f_init();
782
783 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
784 vc_conn.done;
785
786 f_cleanup();
787}
788
789friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100790 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200791 timer T := 5.0;
792 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100793 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200794 T.start;
795 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100796 [] 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 +0200797 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
798 }
Harald Welte16357a92020-11-17 18:20:00 +0100799 [] 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 +0200800 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
801 mtc.stop;
802 }
803 [] T.timeout {
804 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
805 mtc.stop;
806 }
807 }
808 return '00'O;
809}
810
811friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100812 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200813 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100814 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 +0200815 T.start;
816 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100817 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
818 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200819 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
820 mtc.stop;
821 }
822 [] T.timeout {
823 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
824 mtc.stop;
825 }
826 }
827}
828
829
Harald Welte92686012020-11-15 21:45:49 +0100830/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
831private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100832 var integer ran_idx := 0;
833 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100834 var integer i;
835
Harald Welte0d5fceb2020-11-29 16:04:07 +0100836 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100837 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100838 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 +0100839 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100840 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 +0100841
Harald Welte0d5fceb2020-11-29 16:04:07 +0100842 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100843 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100844 }
845 setverdict(pass);
846}
847
848testcase TC_ul_unitdata() runs on test_CT
849{
850 var BSSGP_ConnHdlr vc_conn;
851 f_init();
852
853 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
854 vc_conn.done;
855 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
856
857 f_cleanup();
858}
859
Harald Welte78d8db92020-11-15 23:27:27 +0100860/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
861private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
862 var integer i;
863
Harald Welte0d5fceb2020-11-29 16:04:07 +0100864 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100865 var octetstring payload := f_rnd_octstring(i);
866 var template (value) PDU_BSSGP pdu_tx :=
867 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
868 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
869 var template (present) PDU_BSSGP pdu_rx :=
870 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
871
Harald Welte0d5fceb2020-11-29 16:04:07 +0100872 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100873 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100874 }
875 setverdict(pass);
876}
877
878testcase TC_dl_unitdata() runs on test_CT
879{
880 var BSSGP_ConnHdlr vc_conn;
881 f_init();
882
883 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
884 vc_conn.done;
885 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
886
887 f_cleanup();
888}
Harald Welte92686012020-11-15 21:45:49 +0100889
Harald Welte6dc2ac42020-11-16 09:16:17 +0100890private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
891 var integer i;
892
893 for (i := 0; i < 10; i := i+1) {
894 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
895 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
896 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
897
Harald Welte22ef5d92020-11-16 13:35:14 +0100898 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100899 }
900 setverdict(pass);
901}
902testcase TC_ra_capability() runs on test_CT
903{
904 var BSSGP_ConnHdlr vc_conn;
905 f_init();
906
907 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
908 vc_conn.done;
909 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
910
911 f_cleanup();
912}
913
Daniel Willmannace3ece2020-11-16 19:53:26 +0100914private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
915 var integer i;
916 var OCT1 tag;
917 for (i := 0; i < 10; i := i+1) {
918 tag := int2oct(23 + i, 1);
919 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
920 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
921 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
922
923 f_pcu2sgsn(pdu_tx, pdu_rx);
924
925 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
926 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
927 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
928
929 f_sgsn2pcu(pdu_tx, pdu_rx);
930 }
931 setverdict(pass);
932}
933testcase TC_ra_capability_upd() runs on test_CT
934{
935 var BSSGP_ConnHdlr vc_conn;
936 f_init();
937
Daniel Willmann54833f22020-11-19 15:43:52 +0100938 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100939 vc_conn.done;
940 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
941
942 f_cleanup();
943}
944
Daniel Willmann165d6612020-11-19 14:27:29 +0100945private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
946 var integer i;
947 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
948 for (i := 0; i < 10; i := i+1) {
949 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
950 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
951 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
952
953 f_pcu2sgsn(pdu_tx, pdu_rx);
954 }
955 setverdict(pass);
956}
957testcase TC_radio_status() runs on test_CT
958{
959 var BSSGP_ConnHdlr vc_conn;
960 f_init();
961
Daniel Willmann54833f22020-11-19 15:43:52 +0100962 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100963 vc_conn.done;
964 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
965
966 f_cleanup();
967}
968
Harald Welte3807ed12020-11-24 19:05:22 +0100969private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100970 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100971
Daniel Willmannfa67f492020-11-19 15:48:05 +0100972 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100973 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100974 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100975 var OCT4 tlli := f_gprs_tlli_random();
976 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100977 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100978 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100979
Harald Welte3807ed12020-11-24 19:05:22 +0100980 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100981
Harald Welte3807ed12020-11-24 19:05:22 +0100982 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100983 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100984 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100985
Harald Welte3807ed12020-11-24 19:05:22 +0100986 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100987
988 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100989 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100990 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100991 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100992
Harald Welte3807ed12020-11-24 19:05:22 +0100993 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100994 }
995 setverdict(pass);
996}
Harald Welte3807ed12020-11-24 19:05:22 +0100997testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100998{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100999 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001000 f_global_init();
1001 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001002 f_cleanup();
1003}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001004
Harald Welte3807ed12020-11-24 19:05:22 +01001005private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001006 var integer i;
1007
1008 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001009 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001010 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001011 var OCT4 tlli := f_gprs_tlli_random();
1012 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001013 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001014 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001015
Harald Welte3807ed12020-11-24 19:05:22 +01001016 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001017
Harald Welte3807ed12020-11-24 19:05:22 +01001018 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001019 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001020 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001021
Harald Welte3807ed12020-11-24 19:05:22 +01001022 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001023
1024 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001025 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001026 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001027 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001028
Harald Welte3807ed12020-11-24 19:05:22 +01001029 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001030 }
1031 setverdict(pass);
1032}
Harald Welte3807ed12020-11-24 19:05:22 +01001033testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001034{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001035 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001036 f_global_init();
1037 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001038 f_cleanup();
1039}
1040
Harald Weltef8ef0282020-11-18 12:16:59 +01001041/* test the load-sharing between multiple NS-VC on the BSS side */
1042private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1043 var integer i;
1044
1045 for (i := 0; i < 10; i := i+1) {
1046 var octetstring payload := f_rnd_octstring(i);
1047 var template (value) PDU_BSSGP pdu_tx :=
1048 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1049 SGSN[0].send(pdu_tx);
1050 }
1051 setverdict(pass);
1052}
1053testcase TC_load_sharing_dl() runs on test_CT_NS
1054{
1055 const integer num_ue := 10;
1056 var BSSGP_ConnHdlr vc_conn[num_ue];
1057 f_init();
1058
1059 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1060 * side so we get the raw NsUnitdataIndication and hence observe different
1061 * NSVCI */
1062 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1063 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1064
1065 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1066 * of the NS-VC is ALIVE/UNBLOCKED */
1067 f_sleep(3.0);
1068
1069 /* start parallel components generating DL-UNITDATA from the SGSN side */
1070 for (var integer i:= 0; i < num_ue; i := i+1) {
1071 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1072 }
1073
1074 /* now start counting all the messages that were queued before */
1075 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1076 var ro_integer rx_count := { 0, 0, 0, 0 };
1077 timer T := 2.0;
1078 T.start;
1079 alt {
1080 [] as_NsUdiCount(0, rx_count);
1081 [] as_NsUdiCount(1, rx_count);
1082 [] as_NsUdiCount(2, rx_count);
1083 [] as_NsUdiCount(3, rx_count);
1084 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1085 [] NS.receive(NsStatusIndication:?) { repeat; }
1086 [] NS.receive {
1087 setverdict(fail, "Rx unexpected NS");
1088 mtc.stop;
1089 }
1090 [] T.timeout {
1091 }
1092 }
1093 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1094 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1095 if (rx_count[i] == 0) {
1096 setverdict(fail, "Data not shared over all NSVC");
1097 }
1098 }
1099 setverdict(pass);
1100}
1101private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1102 var NsUnitdataIndication udi;
1103 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1104 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1105 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1106 repeat;
1107 }
1108}
1109type component test_CT_NS extends test_CT {
1110 port NS_PT NS;
1111};
1112
1113
Harald Welte0e188242020-11-22 21:46:48 +01001114/***********************************************************************
1115 * PAGING PS procedure
1116 ***********************************************************************/
1117
1118private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1119 boolean use_sig := false)
1120runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1121 var template (value) PDU_BSSGP pdu_tx;
1122 var template (present) PDU_BSSGP pdu_rx;
1123 /* we always specify '0' as BVCI in the templates below, as we override it with
1124 * 'p4' later anyway */
1125 pdu_rx := tr_BSSGP_PS_PAGING(0);
1126 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1127 if (ispresent(g_pars.p_tmsi)) {
1128 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1129 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1130 } else {
1131 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1132 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1133 }
1134 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1135 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1136 if (use_sig == false) {
1137 SGSN[sgsn_idx].send(pdu_tx);
1138 } else {
1139 SGSN_SIG[sgsn_idx].send(pdu_tx);
1140 }
1141 return pdu_rx;
1142}
1143
1144/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1145 * specified PCU index */
1146private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1147 boolean use_sig := false,integer pcu_idx := 0)
1148runs on BSSGP_ConnHdlr {
1149 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001150 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001151 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1152 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1153 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1154 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1155 timer T := 2.0;
1156 T.start;
1157 alt {
Daniel Willmann1a859712020-12-04 00:59:45 +01001158 [not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001159 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001160 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001161 repeat;
1162 }
1163 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1164 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1165 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001166 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001167 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001168 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001169 repeat;
1170 }
1171 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1172 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1173 }
1174 [] any from PCU.receive(exp_rx) {
1175 setverdict(fail, "Paging received on unexpected BVC");
1176 }
1177 [] any from PCU_SIG.receive(exp_rx) {
1178 setverdict(fail, "Paging received on unexpected BVC");
1179 }
1180 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1181 setverdict(fail, "Different Paging than expected received PTP BVC");
1182 }
1183 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1184 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1185 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001186 [not test_done] T.timeout {
1187 setverdict(fail, "Timeout waiting for paging");
1188 }
1189 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001190 }
1191}
1192
Harald Welte7462a592020-11-23 22:07:07 +01001193/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1194private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1195 boolean use_sig := false)
1196runs on BSSGP_ConnHdlr {
1197 var template (present) PDU_BSSGP exp_rx;
1198 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1199 /* Expect paging to propagate to no BSS */
1200 timer T := 2.0;
1201 T.start;
1202 alt {
1203 [] any from PCU.receive(exp_rx) {
1204 setverdict(fail, "Paging received on unexpected BVC");
1205 }
1206 [] any from PCU_SIG.receive(exp_rx) {
1207 setverdict(fail, "Paging received on unexpected BVC");
1208 }
1209 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1210 setverdict(fail, "Different Paging received on PTP BVC");
1211 }
1212 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1213 setverdict(fail, "Different Paging received on SIGNALING BVC");
1214 }
1215 [] T.timeout {
1216 setverdict(pass);
1217 }
1218 }
1219}
1220
Harald Welte0e188242020-11-22 21:46:48 +01001221private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1222{
1223 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1224 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1225 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1226}
1227testcase TC_paging_ps_ptp_bss() runs on test_CT {
1228 var BSSGP_ConnHdlr vc_conn;
1229 f_init();
1230
1231 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1232 vc_conn.done;
1233
1234 f_cleanup();
1235}
1236
1237/* PS-PAGING on PTP-BVC for Location Area */
1238private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1239{
1240 var template (present) PDU_BSSGP exp_rx;
1241 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1242 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1243 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1244}
1245testcase TC_paging_ps_ptp_lac() runs on test_CT {
1246 var BSSGP_ConnHdlr vc_conn;
1247 f_init();
1248
1249 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1250 vc_conn.done;
1251
1252 f_cleanup();
1253}
1254
Harald Welte7462a592020-11-23 22:07:07 +01001255/* PS-PAGING on PTP-BVC for unknown Location Area */
1256private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1257{
1258 var GSM_Types.LocationAreaIdentification unknown_la := {
1259 mcc_mnc := '567F99'H,
1260 lac := 33333
1261 };
1262 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1263 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1264}
1265testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1266 var BSSGP_ConnHdlr vc_conn;
1267 f_init();
1268
1269 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1270 vc_conn.done;
1271
1272 f_cleanup();
1273}
1274
Harald Welte0e188242020-11-22 21:46:48 +01001275/* PS-PAGING on PTP-BVC for Routeing Area */
1276private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1277{
1278 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1279 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1280 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1281}
1282testcase TC_paging_ps_ptp_rac() runs on test_CT {
1283 var BSSGP_ConnHdlr vc_conn;
1284 f_init();
1285
1286 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1287 vc_conn.done;
1288
1289 f_cleanup();
1290}
1291
Harald Welte7462a592020-11-23 22:07:07 +01001292/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1293private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1294{
1295 var RoutingAreaIdentification unknown_ra := {
1296 lai := {
1297 mcc_mnc := '567F99'H,
1298 lac := 33333
1299 },
1300 rac := 254
1301 };
1302 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1303 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1304}
1305testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1306 var BSSGP_ConnHdlr vc_conn;
1307 f_init();
1308
1309 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1310 vc_conn.done;
1311
1312 f_cleanup();
1313}
1314
Harald Welte0e188242020-11-22 21:46:48 +01001315/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1316private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1317{
1318 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1319 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1320}
1321testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1322 var BSSGP_ConnHdlr vc_conn;
1323 f_init();
1324
1325 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1326 vc_conn.done;
1327
1328 f_cleanup();
1329}
1330
Harald Welte7462a592020-11-23 22:07:07 +01001331/* PS-PAGING on PTP-BVC for unknown BVCI */
1332private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1333{
1334 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1335 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1336}
1337testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1338 var BSSGP_ConnHdlr vc_conn;
1339 f_init();
1340
1341 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1342 vc_conn.done;
1343
1344 f_cleanup();
1345}
1346
Harald Welte0e188242020-11-22 21:46:48 +01001347/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1348private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1349runs on BSSGP_ConnHdlr {
1350[] PCU_SIG[pcu_idx].receive(exp_rx) {
1351 if (ro_integer_contains(roi, pcu_idx)) {
1352 setverdict(fail, "Received multiple paging on same SIG BVC");
1353 }
1354 roi := roi & { pcu_idx };
1355 repeat;
1356 }
1357[] PCU[pcu_idx].receive(exp_rx) {
1358 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1359 }
1360[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1361 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1362 }
1363[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1364 setverdict(fail, "Different Paging than expected received PTP BVC");
1365 }
1366}
1367
1368type record of default ro_default;
1369
1370/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1371private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1372 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1373{
1374 var template (present) PDU_BSSGP exp_rx;
1375 exp_rx := f_send_paging_ps(p4, 0, true);
1376
1377 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1378 var ro_default defaults := {};
1379 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1380 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1381 defaults := defaults & { d };
1382 }
1383 f_sleep(2.0);
1384 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1385 deactivate(defaults[i]);
1386 }
1387 log("Paging received on PCU ", g_roi);
1388
1389 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1390 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1391 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1392 if (exp_on_i and not rx_on_i) {
1393 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1394 }
1395 if (not exp_on_i and rx_on_i) {
1396 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1397 }
1398 }
1399 setverdict(pass);
1400}
1401
1402/* PS-PAGING on SIG-BVC for BSS Area */
1403private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1404{
1405 /* we expect the paging to arrive on all three NSE */
1406 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1407}
1408testcase TC_paging_ps_sig_bss() runs on test_CT {
1409 var BSSGP_ConnHdlr vc_conn;
1410 f_init();
1411
1412 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1413 vc_conn.done;
1414
1415 f_cleanup();
1416}
1417
1418/* PS-PAGING on SIG-BVC for Location Area */
1419private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1420{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001421 /* The first LAC (13135) is shared by all three NSEs */
1422 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1423 /* Reset state */
1424 g_roi := {};
1425 /* Make LAC (13300) available on pcu index 2 */
1426 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1427 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 +01001428}
1429testcase TC_paging_ps_sig_lac() runs on test_CT {
1430 var BSSGP_ConnHdlr vc_conn;
1431 f_init();
1432
1433 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1434 vc_conn.done;
1435
1436 f_cleanup();
1437}
1438
Harald Welte7462a592020-11-23 22:07:07 +01001439/* PS-PAGING on SIG-BVC for unknown Location Area */
1440private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1441{
1442 var GSM_Types.LocationAreaIdentification unknown_la := {
1443 mcc_mnc := '567F99'H,
1444 lac := 33333
1445 };
1446 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1447}
1448testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1449 var BSSGP_ConnHdlr vc_conn;
1450 f_init();
1451
1452 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1453 vc_conn.done;
1454
1455 f_cleanup();
1456}
1457
Harald Welte0e188242020-11-22 21:46:48 +01001458/* PS-PAGING on SIG-BVC for Routeing Area */
1459private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1460{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001461 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001462 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 +01001463 g_roi := {};
1464 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1465 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1466 g_roi := {};
1467 /* PCU index 2 has two matching BVCs with the RA ID */
1468 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1469 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 +01001470}
1471testcase TC_paging_ps_sig_rac() runs on test_CT {
1472 var BSSGP_ConnHdlr vc_conn;
1473 f_init();
1474
1475 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1476 vc_conn.done;
1477
1478 f_cleanup();
1479}
1480
Harald Welte7462a592020-11-23 22:07:07 +01001481/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1482private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1483{
1484 var RoutingAreaIdentification unknown_ra := {
1485 lai := {
1486 mcc_mnc := '567F99'H,
1487 lac := 33333
1488 },
1489 rac := 254
1490 };
1491 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1492}
1493testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1494 var BSSGP_ConnHdlr vc_conn;
1495 f_init();
1496
1497 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1498 vc_conn.done;
1499
1500 f_cleanup();
1501}
1502
Harald Welte0e188242020-11-22 21:46:48 +01001503/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1504private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1505{
1506 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1507}
1508testcase TC_paging_ps_sig_bvci() runs on test_CT {
1509 var BSSGP_ConnHdlr vc_conn;
1510 f_init();
1511
1512 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1513 vc_conn.done;
1514
1515 f_cleanup();
1516}
1517
Harald Welte7462a592020-11-23 22:07:07 +01001518/* PS-PAGING on SIG-BVC for unknown BVCI */
1519private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1520{
1521 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1522}
1523testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1524 var BSSGP_ConnHdlr vc_conn;
1525 f_init();
1526
1527 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1528 vc_conn.done;
1529
1530 f_cleanup();
1531}
1532
1533
Harald Welte0e188242020-11-22 21:46:48 +01001534
1535/***********************************************************************
1536 * PAGING CS procedure
1537 ***********************************************************************/
1538
1539private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1540 boolean use_sig := false)
1541runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1542 var template (value) PDU_BSSGP pdu_tx;
1543 var template (present) PDU_BSSGP pdu_rx;
1544 /* we always specify '0' as BVCI in the templates below, as we override it with
1545 * 'p4' later anyway */
1546 pdu_rx := tr_BSSGP_CS_PAGING(0);
1547 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1548 if (ispresent(g_pars.p_tmsi)) {
1549 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1550 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1551 } else {
1552 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1553 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1554 }
1555 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1556 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1557 if (use_sig == false) {
1558 SGSN[sgsn_idx].send(pdu_tx);
1559 } else {
1560 SGSN_SIG[sgsn_idx].send(pdu_tx);
1561 }
1562 return pdu_rx;
1563}
1564
1565/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1566 * specified PCU index */
1567private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1568 boolean use_sig := false,integer pcu_idx := 0)
1569runs on BSSGP_ConnHdlr {
1570 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001571 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001572 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1573 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1574 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1575 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1576 timer T := 2.0;
1577 T.start;
1578 alt {
Daniel Willmann1a859712020-12-04 00:59:45 +01001579 [not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001580 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001581 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001582 repeat;
1583 }
1584 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1585 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1586 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001587 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001588 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001589 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001590 repeat;
1591 }
1592 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1593 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1594 }
1595 [] any from PCU.receive(exp_rx) {
1596 setverdict(fail, "Paging received on unexpected BVC");
1597 }
1598 [] any from PCU_SIG.receive(exp_rx) {
1599 setverdict(fail, "Paging received on unexpected BVC");
1600 }
1601 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1602 setverdict(fail, "Different Paging than expected received PTP BVC");
1603 }
1604 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1605 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1606 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001607 [not test_done] T.timeout {
1608 setverdict(fail, "Timeout while waiting for paging")
1609 }
1610 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001611 }
1612}
1613
Harald Welte7462a592020-11-23 22:07:07 +01001614/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1615private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1616 boolean use_sig := false)
1617runs on BSSGP_ConnHdlr {
1618 var template (present) PDU_BSSGP exp_rx;
1619 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1620 /* Expect paging to propagate to no BSS */
1621 timer T := 2.0;
1622 T.start;
1623 alt {
1624 [] any from PCU.receive(exp_rx) {
1625 setverdict(fail, "Paging received on unexpected BVC");
1626 }
1627 [] any from PCU_SIG.receive(exp_rx) {
1628 setverdict(fail, "Paging received on unexpected BVC");
1629 }
1630 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1631 setverdict(fail, "Different Paging received on PTP BVC");
1632 }
1633 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1634 setverdict(fail, "Different Paging received on SIGNALING BVC");
1635 }
1636 [] T.timeout {
1637 setverdict(pass);
1638 }
1639 }
1640}
1641
Harald Welte0e188242020-11-22 21:46:48 +01001642private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1643{
1644 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1645 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1646 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1647}
1648testcase TC_paging_cs_ptp_bss() runs on test_CT {
1649 var BSSGP_ConnHdlr vc_conn;
1650 f_init();
1651
1652 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1653 vc_conn.done;
1654
1655 f_cleanup();
1656}
1657
1658/* CS-PAGING on PTP-BVC for Location Area */
1659private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1660{
1661 var template (present) PDU_BSSGP exp_rx;
1662 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1663 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1664 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1665}
1666testcase TC_paging_cs_ptp_lac() runs on test_CT {
1667 var BSSGP_ConnHdlr vc_conn;
1668 f_init();
1669
1670 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1671 vc_conn.done;
1672
1673 f_cleanup();
1674}
1675
Harald Welte7462a592020-11-23 22:07:07 +01001676/* CS-PAGING on PTP-BVC for unknown Location Area */
1677private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1678{
1679 var GSM_Types.LocationAreaIdentification unknown_la := {
1680 mcc_mnc := '567F99'H,
1681 lac := 33333
1682 };
1683 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1684 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1685}
1686testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1687 var BSSGP_ConnHdlr vc_conn;
1688 f_init();
1689
1690 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1691 vc_conn.done;
1692
1693 f_cleanup();
1694}
1695
Harald Welte0e188242020-11-22 21:46:48 +01001696/* CS-PAGING on PTP-BVC for Routeing Area */
1697private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1698{
1699 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1700 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1701 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1702}
1703testcase TC_paging_cs_ptp_rac() runs on test_CT {
1704 var BSSGP_ConnHdlr vc_conn;
1705 f_init();
1706
1707 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1708 vc_conn.done;
1709
1710 f_cleanup();
1711}
1712
Harald Welte7462a592020-11-23 22:07:07 +01001713/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1714private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1715{
1716 var RoutingAreaIdentification unknown_ra := {
1717 lai := {
1718 mcc_mnc := '567F99'H,
1719 lac := 33333
1720 },
1721 rac := 254
1722 };
1723 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1724 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1725}
1726testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1727 var BSSGP_ConnHdlr vc_conn;
1728 f_init();
1729
1730 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1731 vc_conn.done;
1732
1733 f_cleanup();
1734}
1735
Harald Welte0e188242020-11-22 21:46:48 +01001736/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1737private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1738{
1739 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1740 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1741}
1742testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1743 var BSSGP_ConnHdlr vc_conn;
1744 f_init();
1745
1746 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1747 vc_conn.done;
1748
1749 f_cleanup();
1750}
1751
Harald Welte7462a592020-11-23 22:07:07 +01001752/* CS-PAGING on PTP-BVC for unknown BVCI */
1753private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1754{
1755 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1756 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1757}
1758testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
1761
1762 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1763 vc_conn.done;
1764
1765 f_cleanup();
1766}
1767
Harald Welte0e188242020-11-22 21:46:48 +01001768/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1769private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1770 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1771{
1772 var template (present) PDU_BSSGP exp_rx;
1773 exp_rx := f_send_paging_cs(p4, 0, true);
1774
1775 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1776 var ro_default defaults := {};
1777 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1778 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1779 defaults := defaults & { d };
1780 }
1781 f_sleep(2.0);
1782 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1783 deactivate(defaults[i]);
1784 }
1785 log("Paging received on PCU ", g_roi);
1786
1787 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1788 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1789 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1790 if (exp_on_i and not rx_on_i) {
1791 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1792 }
1793 if (not exp_on_i and rx_on_i) {
1794 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1795 }
1796 }
1797 setverdict(pass);
1798}
1799
1800/* CS-PAGING on SIG-BVC for BSS Area */
1801private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1802{
1803 /* we expect the paging to arrive on all three NSE */
1804 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1805}
1806testcase TC_paging_cs_sig_bss() runs on test_CT {
1807 var BSSGP_ConnHdlr vc_conn;
1808 f_init();
1809
1810 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1811 vc_conn.done;
1812
1813 f_cleanup();
1814}
1815
1816/* CS-PAGING on SIG-BVC for Location Area */
1817private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1818{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001819 /* The first LAC (13135) is shared by all three NSEs */
1820 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1821 /* Reset state */
1822 g_roi := {};
1823 /* Make LAC (13300) available on pcu index 2 */
1824 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1825 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 +01001826}
1827testcase TC_paging_cs_sig_lac() runs on test_CT {
1828 var BSSGP_ConnHdlr vc_conn;
1829 f_init();
1830
1831 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1832 vc_conn.done;
1833
1834 f_cleanup();
1835}
1836
Harald Welte7462a592020-11-23 22:07:07 +01001837/* CS-PAGING on SIG-BVC for unknown Location Area */
1838private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1839{
1840 var GSM_Types.LocationAreaIdentification unknown_la := {
1841 mcc_mnc := '567F99'H,
1842 lac := 33333
1843 };
1844 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1845}
1846testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1847 var BSSGP_ConnHdlr vc_conn;
1848 f_init();
1849
1850 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1851 vc_conn.done;
1852
1853 f_cleanup();
1854}
1855
Harald Welte0e188242020-11-22 21:46:48 +01001856/* CS-PAGING on SIG-BVC for Routeing Area */
1857private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1858{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001859 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001860 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 +01001861 g_roi := {};
1862 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1863 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1864 g_roi := {};
1865 /* PCU index 2 has two matching BVCs with the RA ID */
1866 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1867 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 +01001868}
1869testcase TC_paging_cs_sig_rac() runs on test_CT {
1870 var BSSGP_ConnHdlr vc_conn;
1871 f_init();
1872
1873 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1874 vc_conn.done;
1875
1876 f_cleanup();
1877}
1878
Harald Welte7462a592020-11-23 22:07:07 +01001879/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1880private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1881{
1882 var RoutingAreaIdentification unknown_ra := {
1883 lai := {
1884 mcc_mnc := '567F99'H,
1885 lac := 33333
1886 },
1887 rac := 254
1888 };
1889 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1890}
1891testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1892 var BSSGP_ConnHdlr vc_conn;
1893 f_init();
1894
1895 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1896 vc_conn.done;
1897
1898 f_cleanup();
1899}
1900
Harald Welte0e188242020-11-22 21:46:48 +01001901/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1902private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1903{
1904 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1905}
1906testcase TC_paging_cs_sig_bvci() runs on test_CT {
1907 var BSSGP_ConnHdlr vc_conn;
1908 f_init();
1909
1910 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1911 vc_conn.done;
1912
1913 f_cleanup();
1914}
1915
Harald Welte7462a592020-11-23 22:07:07 +01001916/* CS-PAGING on SIG-BVC for unknown BVCI */
1917private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1918{
1919 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1920}
1921testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1922 var BSSGP_ConnHdlr vc_conn;
1923 f_init();
1924
1925 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1926 vc_conn.done;
1927
1928 f_cleanup();
1929}
1930
Harald Welte4f91c3b2020-12-09 12:25:51 +01001931/***********************************************************************
1932 * FLUSH-LL procedure
1933 ***********************************************************************/
1934
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001935private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1936 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1937 var integer i;
1938 for (i := 0; i < 10; i := i+1) {
1939 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1940 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1941 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1942
1943 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1944
1945 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1946 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1947 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1948
1949 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1950 }
1951 setverdict(pass);
1952}
1953testcase TC_flush_ll() runs on test_CT
1954{
1955 var BSSGP_ConnHdlr vc_conn;
1956 f_init();
1957
1958 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1959 vc_conn.done;
1960 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1961
1962 f_cleanup();
1963}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001964
Harald Welte4f91c3b2020-12-09 12:25:51 +01001965/***********************************************************************
1966 * SGSN-INVOKE-TRACE procedure
1967 ***********************************************************************/
1968
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001969private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1970runs on GlobalTest_CT {
1971[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1972 if (ro_integer_contains(roi, pcu_idx)) {
1973 setverdict(fail, "Received multiple on same SIG BVC");
1974 }
1975 roi := roi & { pcu_idx };
1976 repeat;
1977 }
1978}
1979/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1980testcase TC_trace() runs on GlobalTest_CT
1981{
1982 var BSSGP_ConnHdlr vc_conn;
1983 f_init();
1984 f_global_init();
1985
1986 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1987 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1988
1989 var ro_default defaults := {};
1990 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1991 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1992 }
1993 G_SGSN[0].send(pdu_tx);
1994 f_sleep(2.0);
1995 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1996 deactivate(defaults[i]);
1997 }
1998
1999 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2000 if (not ro_integer_contains(g_roi, i)) {
2001 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2002 }
2003 }
2004 setverdict(pass);
2005
2006 f_cleanup();
2007}
2008
Harald Welte4f91c3b2020-12-09 12:25:51 +01002009/***********************************************************************
2010 * LLC-DISCARDED procedure
2011 ***********************************************************************/
2012
Harald Weltec0351d12020-11-27 22:49:02 +01002013private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2014 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2015
2016 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2017 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2018 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2019
2020 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2021
2022 setverdict(pass);
2023}
2024/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2025testcase TC_llc_discarded() runs on test_CT
2026{
2027 var BSSGP_ConnHdlr vc_conn;
2028 f_init();
2029
2030 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2031 vc_conn.done;
2032 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2033
2034 f_cleanup();
2035}
2036
Harald Welte4f91c3b2020-12-09 12:25:51 +01002037/***********************************************************************
2038 * OVERLOAD procedure
2039 ***********************************************************************/
2040
Harald Weltef20af412020-11-28 16:11:11 +01002041/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2042testcase TC_overload() runs on GlobalTest_CT
2043{
2044 f_init();
2045 f_global_init();
2046
2047 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2048 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2049
2050 var ro_default defaults := {};
2051 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2052 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2053 }
2054 G_SGSN[0].send(pdu_tx);
2055 f_sleep(2.0);
2056 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2057 deactivate(defaults[i]);
2058 }
2059
2060 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2061 if (not ro_integer_contains(g_roi, i)) {
2062 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2063 }
2064 }
2065 setverdict(pass);
2066
2067 f_cleanup();
2068}
2069
Harald Welte4f91c3b2020-12-09 12:25:51 +01002070/***********************************************************************
2071 * BVC-BLOCK / BVC-UNBLOCK procedure
2072 ***********************************************************************/
2073
Harald Welte239aa502020-11-24 23:14:20 +01002074private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2075{
2076 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2077 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2078 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2079
2080 SGSN_MGMT.clear;
2081 PCU_MGMT.clear;
2082
2083 /* block the PTP BVC from the PCU side */
2084 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2085 /* expect state on both PCU and SGSN side to change */
2086 interleave {
2087 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2088 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2089 }
2090 setverdict(pass);
2091}
2092testcase TC_bvc_block_ptp() runs on test_CT
2093{
2094 f_init();
2095 f_sleep(1.0);
2096 f_block_ptp_bvc_from_pcu(0, 0);
2097 f_cleanup();
2098}
2099
2100private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2101{
2102 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2103 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2104 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2105
2106 SGSN_MGMT.clear;
2107 PCU_MGMT.clear;
2108
2109 /* block the PTP BVC from the PCU side */
2110 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2111 /* expect state on both PCU and SGSN side to change */
2112 interleave {
2113 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2114 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2115 }
2116 setverdict(pass);
2117}
2118testcase TC_bvc_unblock_ptp() runs on test_CT
2119{
2120 f_init();
2121 f_sleep(1.0);
2122 f_block_ptp_bvc_from_pcu(0, 0);
2123 f_sleep(1.0);
2124 f_unblock_ptp_bvc_from_pcu(0, 0);
2125 f_cleanup();
2126}
2127
Harald Welte4f91c3b2020-12-09 12:25:51 +01002128/***********************************************************************
2129 * BVC-RESET procedure
2130 ***********************************************************************/
2131
Harald Welte60a8ec72020-11-25 17:12:53 +01002132private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2133[] pt.receive(BssgpStatusIndication:?) { repeat; }
2134}
2135private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2136 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2137 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2138 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2139 }
2140 }
2141 return null;
2142}
2143private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2144{
2145 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2146 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2147 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2148 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2149 var default d;
2150
2151 SGSN_MGMT.clear;
2152 PCU_MGMT.clear;
2153
2154 /* block the PTP BVC from the PCU side */
2155 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2156 /* expect state on both PCU and SGSN side to change */
2157 d := activate(as_ignore_status(SGSN_MGMT));
2158 interleave {
2159 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2160 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2161 }
2162 deactivate(d);
2163 setverdict(pass);
2164}
2165/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2166testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2167{
2168 f_init();
2169 f_sleep(3.0);
2170 f_reset_ptp_bvc_from_pcu(0, 0);
2171 f_cleanup();
2172}
2173
Harald Welte16786e92020-11-27 19:11:56 +01002174private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2175runs on test_CT {
2176 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2177 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2178 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002179 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002180 }
2181}
2182/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2183testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2184
2185 f_init();
2186 f_sleep(3.0);
2187
2188 /* Start BVC-RESET procedure for BVCI=0 */
2189 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2190
2191 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2192 var ro_default defaults := {};
2193 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2194 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2195 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2196 defaults := defaults & { d };
2197 }
2198
2199 timer T := 3.0;
2200 T.start;
2201 alt {
2202 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2203 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2204 }
2205 [] T.timeout;
2206 }
2207
2208 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2209 deactivate(defaults[i]);
2210 }
2211
2212 /* check if BVC-block was received on all expected BVC */
2213 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2214 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2215 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2216 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2217 }
2218 }
2219
2220 /* check if BVC-block was not received on any unexpected BVC is not required as
2221 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002222 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002223 f_cleanup();
2224}
2225
Harald Welte60a8ec72020-11-25 17:12:53 +01002226private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2227{
2228 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2229 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2230 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2231 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2232 var default d;
2233
2234 SGSN_MGMT.clear;
2235 PCU_MGMT.clear;
2236
2237 /* block the PTP BVC from the PCU side */
2238 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2239 /* expect state on both PCU and SGSN side to change */
2240 d := activate(as_ignore_status(PCU_MGMT));
2241 interleave {
2242 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2243 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2244 }
2245 deactivate(d);
2246 setverdict(pass);
2247}
2248/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2249testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2250{
2251 f_init();
2252 f_sleep(3.0);
2253 f_reset_ptp_bvc_from_sgsn(0, 0);
2254 f_cleanup();
2255}
2256
Harald Welte16786e92020-11-27 19:11:56 +01002257private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2258runs on test_CT {
2259 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2260 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2261 roi := roi & { nsei };
2262 }
2263}
2264/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2265testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2266
2267 f_init();
2268 f_sleep(3.0);
2269
2270 /* Start BVC-RESET procedure for BVCI=0 */
2271 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2272
2273 /* Activate altsteps: One for each PCU NSE */
2274 var ro_default defaults := {};
2275 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2276 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2277 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2278 defaults := defaults & { d };
2279 }
2280
2281 f_sleep(3.0);
2282
2283 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2284 deactivate(defaults[i]);
2285 }
2286
2287 /* check if BVC-block was received on all expected BVC */
2288 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2289 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2290 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2291 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2292 }
2293 }
2294
2295 /* check if BVC-block was not received on any unexpected BVC is not required as
2296 * such a message would basically run into 'no matching clause' */
2297
2298 f_cleanup();
2299}
2300
Daniel Willmann423d8f42020-09-08 18:58:22 +02002301control {
2302 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002303 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002304 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002305 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002306 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002307 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002308 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002309 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002310 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002311 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002312 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002313 execute( TC_bvc_block_ptp() );
2314 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002315 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002316 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002317 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002318 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002319 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002320 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2321 execute( TC_load_sharing_dl() );
2322 }
Harald Welte0e188242020-11-22 21:46:48 +01002323
2324 /* PAGING-PS over PTP BVC */
2325 execute( TC_paging_ps_ptp_bss() );
2326 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002327 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002328 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002329 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002330 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002331 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002332
2333 /* PAGING-PS over SIG BVC */
2334 execute( TC_paging_ps_sig_bss() );
2335 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002336 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002337 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002338 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002339 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002340 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002341
2342 /* PAGING-CS over PTP BVC */
2343 execute( TC_paging_cs_ptp_bss() );
2344 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002345 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002346 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002347 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002348 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002349 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002350
2351 /* PAGING-CS over SIG BVC */
2352 execute( TC_paging_cs_sig_bss() );
2353 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002354 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002355 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002356 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002357 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002358 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002359
2360
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002361 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002362}
2363
2364
2365}