blob: f5248aa82c1b88215c75d0c741277fa65b271d5a [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
36
37import from LLC_Types all;
38import from LLC_Templates all;
39
40import from GSM_RR_Types all;
41
Harald Welte6d63f742020-11-15 19:44:04 +010042/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
43const BcdMccMnc c_mcc_mnc := '262F42'H;
44
Harald Welte0d5fceb2020-11-29 16:04:07 +010045/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
46const integer max_fr_info_size := 1600;
47
Daniel Willmann423d8f42020-09-08 18:58:22 +020048modulepar {
Harald Welte77218d02021-01-15 19:59:15 +010049 /* NRI bit-length. 0 for no pooling */
50 integer mp_nri_bitlength := 5;
51 roro_integer mp_sgsn_nri := {
52 { 3 }, /* list of NRIs of first SGSN */
53 { 4 } /* list of NRIs of second SGSN */
54 };
Harald Weltef6e59b02020-12-08 08:29:09 +010055 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010056 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010057 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020059 nsei := 101,
60 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010061 handle_sns := false,
62 nsvc := {
63 {
64 provider := {
65 ip := {
66 address_family := AF_INET,
67 local_udp_port := 7777,
68 local_ip := "127.0.0.1",
69 remote_udp_port := 23000,
70 remote_ip := "127.0.0.1"
71 }
72 },
73 nsvci := 101
74 }
75 }
Harald Welteb978ed62020-12-12 14:01:11 +010076 }, {
77 nsei := 102,
78 role_sgsn := true,
79 handle_sns := false,
80 nsvc := {
81 {
82 provider := {
83 ip := {
84 address_family := AF_INET,
85 local_udp_port := 8888,
86 local_ip := "127.0.0.1",
87 remote_udp_port := 23000,
88 remote_ip := "127.0.0.1"
89 }
90 },
91 nsvci := 102
92 }
93 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020094 }
95 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010096 /* BSS NSEI start at 2000 + x
97 * NSVCI start from value of NSEI + 100
98 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010099 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200100 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100101 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200102 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100103 handle_sns := false,
104 nsvc := {
105 {
106 provider := {
107 ip := {
108 address_family := AF_INET,
109 local_udp_port := 21010,
110 local_ip := "127.0.0.1",
111 remote_udp_port := 23000,
112 remote_ip := "127.0.0.1"
113 }
114 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100115 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100116 }
117 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200118 },
119 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100120 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200121 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100122 handle_sns := false,
123 nsvc := {
124 {
125 provider := {
126 ip := {
127 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100128 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100129 local_ip := "127.0.0.1",
130 remote_udp_port := 23000,
131 remote_ip := "127.0.0.1"
132 }
133 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100134 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100135 }
136 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200137 },
138 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100139 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200140 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100141 handle_sns := false,
142 nsvc := {
143 {
144 provider := {
145 ip := {
146 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100147 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100148 local_ip := "127.0.0.1",
149 remote_udp_port := 23000,
150 remote_ip := "127.0.0.1"
151 }
152 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100153 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100154 }
155 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200156 }
157 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100158 /* BVCI are NSEI*10 + x
159 * The first NSE only has one BVC, the second one 2 and so on
160 * The Cell ID is BVCI + 10000
161 * LAC/RAC are configured in such a way that:
162 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
163 * LAC 13300 is present twice in NSE(2003)
164 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
165 * RAI 13300-0 is present twice in NSE(2003)
166 */
Harald Welte6d63f742020-11-15 19:44:04 +0100167 BssgpConfigs mp_gbconfigs := {
168 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100169 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100170 sgsn_role := false,
171 bvc := {
172 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100173 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100174 cell_id := {
175 ra_id := {
176 lai := {
177 mcc_mnc := c_mcc_mnc,
178 lac := 13135
179 },
180 rac := 0
181 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100182 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100183 },
184 depth := BSSGP_DECODE_DEPTH_BSSGP,
185 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
186 }
187 }
188 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100189 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100190 sgsn_role := false,
191 bvc := {
192 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100194 cell_id := {
195 ra_id := {
196 lai := {
197 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100198 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100199 },
Harald Welte0e188242020-11-22 21:46:48 +0100200 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100201 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100202 cell_id := 30021
203 },
204 depth := BSSGP_DECODE_DEPTH_BSSGP,
205 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
206 },
207 {
208 bvci := 20022,
209 cell_id := {
210 ra_id := {
211 lai := {
212 mcc_mnc := c_mcc_mnc,
213 lac := 13135
214 },
215 rac := 2
216 },
217 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100218 },
219 depth := BSSGP_DECODE_DEPTH_BSSGP,
220 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
221 }
222 }
223 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100224 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100225 sgsn_role := false,
226 bvc := {
227 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100228 bvci := 20031,
229 cell_id := {
230 ra_id := {
231 lai := {
232 mcc_mnc := c_mcc_mnc,
233 lac := 13135
234 },
235 rac := 1
236 },
237 cell_id := 30031
238 },
239 depth := BSSGP_DECODE_DEPTH_BSSGP,
240 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
241 },
242 {
243 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100244 cell_id := {
245 ra_id := {
246 lai := {
247 mcc_mnc := c_mcc_mnc,
248 lac := 13300
249 },
250 rac := 0
251 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100252 cell_id := 30032
253 },
254 depth := BSSGP_DECODE_DEPTH_BSSGP,
255 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
256 },
257 {
258 bvci := 20033,
259 cell_id := {
260 ra_id := {
261 lai := {
262 mcc_mnc := c_mcc_mnc,
263 lac := 13300
264 },
265 rac := 0
266 },
267 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100268 },
269 depth := BSSGP_DECODE_DEPTH_BSSGP,
270 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
271 }
272 }
273 }
274 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200275};
276
Daniel Willmann423d8f42020-09-08 18:58:22 +0200277type record GbInstance {
278 NS_CT vc_NS,
279 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100280 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200281 BssgpConfig cfg
282};
Harald Welte67dc8c22020-11-17 18:32:29 +0100283type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200284
285const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100286type record of GbInstance GbInstances;
287type record of BssgpConfig BssgpConfigs;
288type record of NSConfiguration NSConfigurations;
289type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200290
Harald Welteb978ed62020-12-12 14:01:11 +0100291const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200292
293type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100294 var GbInstances g_pcu;
295 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200296
297 port BSSGP_CT_PROC_PT PROC;
298
Harald Weltefbae83f2020-11-15 23:25:55 +0100299 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
300 port BSSGP_BVC_MGMT_PT PCU_MGMT;
301
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302 port TELNETasp_PT GBPVTY;
303
304 var boolean g_initialized := false;
305 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100306
307 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100308 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200309};
310
311type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100312 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100313 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200314 port BSSGP_PT PCU_SIG[NUM_PCU];
315 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100316 /* component reference to the component to which we're currently connected */
317 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100318 /* BSSGP BVC configuration of the component to which we're currently connected */
319 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100320
321 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100322 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200323 port BSSGP_PT SGSN_SIG[NUM_SGSN];
324 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100325 /* component reference to the component to which we're currently connected */
326 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200327
328 var BSSGP_ConnHdlrPars g_pars;
329 timer g_Tguard;
330 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100331
332 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200333}
334
335type record SGSN_ConnHdlrNetworkPars {
336 boolean expect_ptmsi,
337 boolean expect_auth,
338 boolean expect_ciph
339};
340
341type record BSSGP_ConnHdlrPars {
342 /* IMEI of the simulated ME */
343 hexstring imei,
344 /* IMSI of the simulated MS */
345 hexstring imsi,
346 /* MSISDN of the simulated MS (probably unused) */
347 hexstring msisdn,
348 /* P-TMSI allocated to the simulated MS */
349 OCT4 p_tmsi optional,
350 OCT3 p_tmsi_sig optional,
351 /* TLLI of the simulated MS */
352 OCT4 tlli,
353 OCT4 tlli_old optional,
354 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100355 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100356 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100357 /* The SGSN index to be used within the test */
358 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200359 float t_guard
360};
361
362private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
363 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
364 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
365
366 var RoutingAreaIdentificationV ret := {
367 mccDigit1 := mcc_mnc[0],
368 mccDigit2 := mcc_mnc[1],
369 mccDigit3 := mcc_mnc[2],
370 mncDigit3 := mcc_mnc[3],
371 mncDigit1 := mcc_mnc[4],
372 mncDigit2 := mcc_mnc[5],
373 lac := int2oct(cell_id.ra_id.lai.lac, 16),
374 rac := int2oct(cell_id.ra_id.rac, 8)
375 }
376 return ret;
377};
378
Harald Welte95339432020-12-02 18:50:52 +0100379private function f_fix_create_cb(inout BssgpConfig cfg)
380{
381 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
382 if (not isbound(cfg.bvc[i].create_cb)) {
383 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
384 }
385 }
386}
387
Daniel Willmann423d8f42020-09-08 18:58:22 +0200388private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100389 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
390 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
391 gb.vc_NS := NS_CT.create(ns_id);
392 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200393 /* connect lower end of BSSGP emulation with NS upper port */
394 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
395
Harald Welteb419d0e2020-11-16 16:45:05 +0100396 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
397 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200398
399 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100400 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200401 connect(self:PROC, gb.vc_BSSGP:PROC);
402 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
403 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100404 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100405 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200406 }
Harald Welteb978ed62020-12-12 14:01:11 +0100407 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100408 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200409}
410
411private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100412 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
413 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
414 gb.vc_NS := NS_CT.create(ns_id);
415 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200416 /* connect lower end of BSSGP emulation with NS upper port */
417 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
418
Harald Welteb419d0e2020-11-16 16:45:05 +0100419 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
420 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200421
422 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100423 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200424 connect(self:PROC, gb.vc_BSSGP:PROC);
425 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
426 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100427 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100428 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200429 }
Harald Welteb978ed62020-12-12 14:01:11 +0100430 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100431 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200432}
433
434
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100435private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
436 gb.vc_NS.stop;
437 gb.vc_BSSGP.stop;
438
439 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
440 gb.vc_BSSGP_BVC[i].stop;
441 }
442}
443
Daniel Willmann423d8f42020-09-08 18:58:22 +0200444private function f_init_vty() runs on test_CT {
445 map(self:GBPVTY, system:GBPVTY);
446 f_vty_set_prompts(GBPVTY);
447 f_vty_transceive(GBPVTY, "enable");
448}
449
Harald Weltefbae83f2020-11-15 23:25:55 +0100450type record of integer ro_integer;
451
452private function ro_integer_contains(ro_integer r, integer x) return boolean {
453 for (var integer j := 0; j < lengthof(r); j := j+1) {
454 if (r[j] == x) {
455 return true;
456 }
457 }
458 return false;
459}
460
Harald Welteb978ed62020-12-12 14:01:11 +0100461private type record of ro_integer roro_integer;
462
463/* count the number of unblocked BVCI for each SGSN NSE */
464private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
465runs on test_CT {
466 var BssgpStatusIndication bsi;
467 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
468 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
469 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
470 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
471 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
472 repeat;
473 }
474 }
475 }
476}
477
Harald Welte425d3762020-12-09 14:33:18 +0100478function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100479 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100480 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200481 var integer i;
482
483 if (g_initialized == true) {
484 return;
485 }
486 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200487
Harald Welte425d3762020-12-09 14:33:18 +0100488 g_Tguard.start(t_guard);
489 activate(as_gTguard(g_Tguard));
490
Harald Welteb978ed62020-12-12 14:01:11 +0100491 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100492 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
493 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100494 /* make sure all have a proper crate_cb, which cannot be specified in config file */
495 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100496 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100497 bvcs := bvcs & g_pcu[i].cfg.bvc;
498 }
499
500 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
501 g_sgsn[i].cfg := {
502 nsei := mp_nsconfig_sgsn[i].nsei,
503 sgsn_role := true,
504 bvc := bvcs
505 }
Harald Welte6d63f742020-11-15 19:44:04 +0100506 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200507
508 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100509 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100510 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100511 }
512 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
513 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
514 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
515 }
516
517 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100518 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100519 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200520 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100521 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100522 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100523 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100524
Harald Welteb978ed62020-12-12 14:01:11 +0100525 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
526 bvci_unblocked[i] := {};
527 }
528
Harald Weltefbae83f2020-11-15 23:25:55 +0100529 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100530 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100531 T.start;
532 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100533 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
534 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
535 [] as_count_unblocked4nse(0, bvci_unblocked);
536 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100537 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
538 repeat;
539 }
Harald Welte3c905152020-11-26 20:56:09 +0100540 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
541 repeat;
542 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100543 [] SGSN_MGMT.receive {
544 setverdict(fail, "Received unexpected message on SGSN_MGMT");
545 mtc.stop;
546 }
547
548 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
549 repeat;
550 }
551 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
552 repeat;
553 }
554 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
555 repeat;
556 }
557 [] PCU_MGMT.receive {
558 setverdict(fail, "Received unexpected message on PCU_MGMT");
559 mtc.stop;
560 }
561
562 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100563 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100564 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100565 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100566 }
567 }
568
Harald Welteb978ed62020-12-12 14:01:11 +0100569 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
570 /* iterate over list and check all BVCI */
571 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
572 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
573 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
574 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
575 mtc.stop;
576 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100577 }
578 }
Harald Welte425d3762020-12-09 14:33:18 +0100579
580 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
581 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200582}
583
584function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100585 var integer i;
586
Daniel Willmann491af2a2021-01-08 01:32:51 +0100587 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
588 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
589 * before the component is shutdown and disconnected. */
590 f_sleep(0.2);
591
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100592 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
593 f_destroy_gb(g_sgsn[i]);
594 }
595 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
596 f_destroy_gb(g_pcu[i]);
597 }
598
599 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200600}
601
602type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
603
604/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100605function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
606 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200607runs on test_CT return BSSGP_ConnHdlr {
608 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100609 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100610 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200611
612 var BSSGP_ConnHdlrPars pars := {
613 imei := f_gen_imei(imsi_suffix),
614 imsi := f_gen_imsi(imsi_suffix),
615 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100616 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200617 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100618 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200619 tlli_old := omit,
620 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100621 pcu := g_pcu,
622 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100623 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200624 t_guard := t_guard
625 };
Harald Welte207166c2021-01-16 12:52:30 +0100626 if (not have_ptmsi) {
627 pars.p_tmsi := omit;
628 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200629
630 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200631
Harald Welte25a04b12021-01-17 11:09:49 +0100632 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
633 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200634 vc_conn.start(f_handler_init(fn, id, pars));
635 return vc_conn;
636}
637
Harald Welte207166c2021-01-16 12:52:30 +0100638function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
639 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100640runs on test_CT
641{
642 var integer sgsn_idx, nri_idx;
643 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
644 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
645 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
646 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100647 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
648 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100649 /* Idea: we could also run them in parallel ? */
650 vc_conn.done;
651 }
652 }
653}
654
Harald Welte3dd21b32020-11-17 19:21:00 +0100655/* 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 +0100656private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
657runs on BSSGP_ConnHdlr {
658 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100659 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100660 /* unregister + disconnect from old BVC */
661 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100662 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100663 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
664 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
665 }
666 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100667 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100668 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
669 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
670 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
671 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100672 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100673}
674
675/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
676private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
Harald Welte158becf2020-12-09 12:32:32 +0100677 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100678 /* unregister + disconnect from old BVC */
679 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100680 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100681 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
682 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
683 }
684 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100685 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100686 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
687 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
688 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
689 sgsn_ct[port_idx] := bvc_ct;
690}
691
Harald Welte425d3762020-12-09 14:33:18 +0100692private altstep as_gTguard(timer Tguard) {
693 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200694 setverdict(fail, "Tguard timeout");
695 mtc.stop;
696 }
697}
698
699/* first function called in every ConnHdlr */
700private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
701runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100702 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200703 /* do some common stuff like setting up g_pars */
704 g_pars := pars;
705
706 llc := f_llc_create(false);
707
Harald Welte3dd21b32020-11-17 19:21:00 +0100708 /* default connections on PCU side: First BVC of each NSE/PCU */
709 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100710 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100711 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100712
713 /* default connections on SGSN side: First BVC of each NSE/SGSN */
714 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
715 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100716 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200717
718 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100719 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200720
721 /* call the user-supplied test case function */
722 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100723
724 for (i := 0; i < NUM_SGSN; i := i+1) {
725 if (SGSN_PROC[i].checkstate("Connected")) {
726 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
727 }
728 }
729
730 for (i := 0; i < NUM_PCU; i := i+1) {
731 if (PCU_PROC[i].checkstate("Connected")) {
732 f_client_unregister(g_pars.imsi, PCU_PROC[i])
733 }
734 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200735}
736
Harald Welte1e834f32020-11-15 20:02:59 +0100737private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
738runs on BSSGP_ConnHdlr {
739 PT.call(BSSGP_register_client:{imsi, tlli}) {
740 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
741 }
742}
743
744private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
745runs on BSSGP_ConnHdlr {
746 PT.call(BSSGP_unregister_client:{imsi}) {
747 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
748 }
749}
750
Harald Welte22ef5d92020-11-16 13:35:14 +0100751/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
752friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100753 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
754 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100755 var PDU_BSSGP rx;
756 timer T := 1.0;
757
Daniel Willmann4798fd72020-11-24 16:23:29 +0100758 if (use_sig) {
759 PCU_SIG[pcu_idx].send(tx);
760 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100761 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100762 }
763
Harald Welte22ef5d92020-11-16 13:35:14 +0100764 T.start;
765 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100766 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
767 setverdict(pass);
768 }
Harald Welte158becf2020-12-09 12:32:32 +0100769 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100770 setverdict(pass);
771 }
Harald Welte158becf2020-12-09 12:32:32 +0100772 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100773 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100774 mtc.stop;
775 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100776 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100777 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100778 mtc.stop;
779 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100780 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100781 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100782 mtc.stop;
783 }
784 }
785}
786
787/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
788friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100789 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
790 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100791 var PDU_BSSGP rx;
792 timer T := 1.0;
793
Daniel Willmann4798fd72020-11-24 16:23:29 +0100794 if (use_sig) {
795 SGSN_SIG[sgsn_idx].send(tx);
796 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100797 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100798 }
799
Harald Welte22ef5d92020-11-16 13:35:14 +0100800 T.start;
801 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100802 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
803 setverdict(pass);
804 }
Harald Welte158becf2020-12-09 12:32:32 +0100805 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100806 setverdict(pass);
807 }
Harald Welte158becf2020-12-09 12:32:32 +0100808 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100809 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
810 mtc.stop;
811 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100812 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
813 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
814 mtc.stop;
815 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100816 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100817 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100818 mtc.stop;
819 }
820 }
821}
Harald Welte1e834f32020-11-15 20:02:59 +0100822
Harald Welte3807ed12020-11-24 19:05:22 +0100823/***********************************************************************
824 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
825 ***********************************************************************/
826
827type component GlobalTest_CT extends test_CT {
828 port BSSGP_PT G_PCU[NUM_PCU];
829 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Weltef86f1852021-01-16 21:56:17 +0100830 port BSSGP_PT RIM_PCU[NUM_PCU];
831 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100832};
833
Harald Welte299aa482020-12-09 15:10:55 +0100834/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100835private function f_global_init() runs on GlobalTest_CT {
836 var integer i;
837 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
838 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100839 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100840 }
841 for (i := 0; i < lengthof(g_pcu); i := i+1) {
842 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100843 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100844 }
845}
846
Harald Welte299aa482020-12-09 15:10:55 +0100847/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
848private function f_global_init_ptp() runs on GlobalTest_CT {
849 var integer i;
850 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
851 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
852 }
853 for (i := 0; i < lengthof(g_pcu); i := i+1) {
854 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
855 }
856}
857
Harald Welte3807ed12020-11-24 19:05:22 +0100858/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
859friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
860 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
861 var PDU_BSSGP rx;
862 timer T := 1.0;
863
864 G_PCU[pcu_idx].send(tx);
865 T.start;
866 alt {
867 [] G_SGSN[sgsn_idx].receive(exp_rx) {
868 setverdict(pass);
869 }
870 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
871 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
872 mtc.stop;
873 }
874 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100875 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100876 mtc.stop;
877 }
878 }
879}
880
881/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
882friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
883 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
884 var PDU_BSSGP rx;
885 timer T := 1.0;
886
887 G_SGSN[sgsn_idx].send(tx);
888 T.start;
889 alt {
890 [] G_PCU[pcu_idx].receive(exp_rx) {
891 setverdict(pass);
892 }
893 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
894 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
895 mtc.stop;
896 }
897 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100898 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100899 mtc.stop;
900 }
901 }
902}
903
904
Daniel Willmann423d8f42020-09-08 18:58:22 +0200905/* TODO:
906 * Detach without Attach
907 * SM procedures without attach / RAU
908 * ATTACH / RAU
909 ** with / without authentication
910 ** with / without P-TMSI allocation
911 * re-transmissions of LLC frames
912 * PDP Context activation
913 ** with different GGSN config in SGSN VTY
914 ** with different PDP context type (v4/v6/v46)
915 ** timeout from GGSN
916 ** multiple / secondary PDP context
917 */
918
919private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
920 f_sleep(5.0);
921 setverdict(pass);
922}
923
924testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200925 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100926 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200927 f_cleanup();
928}
929
930friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100931 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200932 timer T := 5.0;
933 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100934 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200935 T.start;
936 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100937 [] 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 +0200938 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
939 }
Harald Welte16357a92020-11-17 18:20:00 +0100940 [] 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 +0200941 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
942 mtc.stop;
943 }
944 [] T.timeout {
945 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
946 mtc.stop;
947 }
948 }
949 return '00'O;
950}
951
952friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100953 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200954 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100955 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 +0200956 T.start;
957 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100958 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
959 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200960 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
961 mtc.stop;
962 }
963 [] T.timeout {
964 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
965 mtc.stop;
966 }
967 }
968}
969
970
Harald Welte92686012020-11-15 21:45:49 +0100971/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
972private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100973 var integer ran_idx := 0;
974 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100975 var integer i;
976
Harald Welte0d5fceb2020-11-29 16:04:07 +0100977 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100978 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100979 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 +0100980 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100981 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 +0100982
Harald Welte0d5fceb2020-11-29 16:04:07 +0100983 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100984 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100985 }
986 setverdict(pass);
987}
988
989testcase TC_ul_unitdata() runs on test_CT
990{
Harald Welte92686012020-11-15 21:45:49 +0100991 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +0100992 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +0100993 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +0100994 f_cleanup();
995}
996
Harald Welte78d8db92020-11-15 23:27:27 +0100997/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
998private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
999 var integer i;
1000
Harald Welte0d5fceb2020-11-29 16:04:07 +01001001 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001002 var octetstring payload := f_rnd_octstring(i);
1003 var template (value) PDU_BSSGP pdu_tx :=
1004 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1005 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1006 var template (present) PDU_BSSGP pdu_rx :=
1007 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
1008
Harald Welte0d5fceb2020-11-29 16:04:07 +01001009 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001010 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001011 }
1012 setverdict(pass);
1013}
1014
1015testcase TC_dl_unitdata() runs on test_CT
1016{
Harald Welte78d8db92020-11-15 23:27:27 +01001017 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001018 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001019 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001020 f_cleanup();
1021}
Harald Welte92686012020-11-15 21:45:49 +01001022
Harald Welte6dc2ac42020-11-16 09:16:17 +01001023private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1024 var integer i;
1025
1026 for (i := 0; i < 10; i := i+1) {
1027 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1028 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1029 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1030
Harald Welte22ef5d92020-11-16 13:35:14 +01001031 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001032 }
1033 setverdict(pass);
1034}
1035testcase TC_ra_capability() runs on test_CT
1036{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001037 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001038 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001039 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001040 f_cleanup();
1041}
1042
Daniel Willmannace3ece2020-11-16 19:53:26 +01001043private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1044 var integer i;
1045 var OCT1 tag;
1046 for (i := 0; i < 10; i := i+1) {
1047 tag := int2oct(23 + i, 1);
1048 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1049 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1050 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1051
1052 f_pcu2sgsn(pdu_tx, pdu_rx);
1053
1054 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1055 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1056 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1057
1058 f_sgsn2pcu(pdu_tx, pdu_rx);
1059 }
1060 setverdict(pass);
1061}
1062testcase TC_ra_capability_upd() runs on test_CT
1063{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001064 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001065 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001066 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001067 f_cleanup();
1068}
1069
Daniel Willmann165d6612020-11-19 14:27:29 +01001070private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1071 var integer i;
1072 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1073 for (i := 0; i < 10; i := i+1) {
1074 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1075 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1076 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1077
1078 f_pcu2sgsn(pdu_tx, pdu_rx);
1079 }
1080 setverdict(pass);
1081}
1082testcase TC_radio_status() runs on test_CT
1083{
Daniel Willmann165d6612020-11-19 14:27:29 +01001084 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001085 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001086 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001087 f_cleanup();
1088}
1089
Harald Welte99ed5072021-01-15 20:38:58 +01001090private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1091 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001092runs on GlobalTest_CT
1093{
1094 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001095 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1096 nri_bitlen := mp_nri_bitlength);
1097 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001098 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1099 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1100 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1101 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1102
1103 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1104 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1105 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1106 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1107
1108 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1109 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1110 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1111 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1112
1113 /* These messages are simple passed through so just also test sending NACK */
1114 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1115 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1116 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1117 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1118}
1119
Harald Weltec5c33732021-01-15 21:04:35 +01001120private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1121runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001122 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001123
Daniel Willmannfa67f492020-11-19 15:48:05 +01001124 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001125 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001126 }
1127 setverdict(pass);
1128}
Harald Welte3807ed12020-11-24 19:05:22 +01001129testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001130{
Harald Weltec5c33732021-01-15 21:04:35 +01001131 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001132 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001133 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001134 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1135 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1136 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1137 }
1138 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001139 f_cleanup();
1140}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001141
Harald Welte99ed5072021-01-15 20:38:58 +01001142private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1143 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001144runs on GlobalTest_CT
1145{
1146 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001147 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1148 nri_bitlen := mp_nri_bitlength);
1149 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001150 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1151 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1152 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1153 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1154
1155 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1156 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1157 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1158 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1159
1160 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1161 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1162 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1163 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1164
1165 /* These messages are simple passed through so just also test sending NACK */
1166 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1167 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1168 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1169 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1170}
1171
Harald Weltec5c33732021-01-15 21:04:35 +01001172private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1173runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001174 var integer i;
1175
Daniel Willmann087a33d2020-11-19 15:58:43 +01001176 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001177 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001178 }
1179 setverdict(pass);
1180}
Harald Welte3807ed12020-11-24 19:05:22 +01001181testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001182{
Harald Weltec5c33732021-01-15 21:04:35 +01001183 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001184 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001185 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001186 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1187 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1188 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1189 }
1190 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001191 f_cleanup();
1192}
1193
Harald Weltef8ef0282020-11-18 12:16:59 +01001194/* test the load-sharing between multiple NS-VC on the BSS side */
1195private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1196 var integer i;
1197
1198 for (i := 0; i < 10; i := i+1) {
1199 var octetstring payload := f_rnd_octstring(i);
1200 var template (value) PDU_BSSGP pdu_tx :=
1201 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001202 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001203 }
1204 setverdict(pass);
1205}
Harald Welte09a1ce42021-01-16 11:18:38 +01001206
1207private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001208{
1209 const integer num_ue := 10;
1210 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001211 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1212 * side so we get the raw NsUnitdataIndication and hence observe different
1213 * NSVCI */
1214 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1215 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1216
1217 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1218 * of the NS-VC is ALIVE/UNBLOCKED */
1219 f_sleep(3.0);
1220
1221 /* start parallel components generating DL-UNITDATA from the SGSN side */
1222 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001223 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001224 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001225 }
1226
1227 /* now start counting all the messages that were queued before */
1228 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1229 var ro_integer rx_count := { 0, 0, 0, 0 };
1230 timer T := 2.0;
1231 T.start;
1232 alt {
1233 [] as_NsUdiCount(0, rx_count);
1234 [] as_NsUdiCount(1, rx_count);
1235 [] as_NsUdiCount(2, rx_count);
1236 [] as_NsUdiCount(3, rx_count);
1237 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1238 [] NS.receive(NsStatusIndication:?) { repeat; }
1239 [] NS.receive {
1240 setverdict(fail, "Rx unexpected NS");
1241 mtc.stop;
1242 }
1243 [] T.timeout {
1244 }
1245 }
1246 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1247 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1248 if (rx_count[i] == 0) {
1249 setverdict(fail, "Data not shared over all NSVC");
1250 }
1251 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001252}
1253
1254testcase TC_load_sharing_dl() runs on test_CT_NS
1255{
1256 var integer sgsn_idx, nri_idx;
1257 f_init();
1258 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1259 f_TC_load_sharing_dl(sgsn_idx);
1260 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001261 setverdict(pass);
1262}
1263private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1264 var NsUnitdataIndication udi;
1265 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1266 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1267 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1268 repeat;
1269 }
1270}
1271type component test_CT_NS extends test_CT {
1272 port NS_PT NS;
1273};
1274
1275
Harald Welte0e188242020-11-22 21:46:48 +01001276/***********************************************************************
1277 * PAGING PS procedure
1278 ***********************************************************************/
1279
1280private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1281 boolean use_sig := false)
1282runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1283 var template (value) PDU_BSSGP pdu_tx;
1284 var template (present) PDU_BSSGP pdu_rx;
1285 /* we always specify '0' as BVCI in the templates below, as we override it with
1286 * 'p4' later anyway */
1287 pdu_rx := tr_BSSGP_PS_PAGING(0);
1288 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1289 if (ispresent(g_pars.p_tmsi)) {
1290 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1291 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1292 } else {
1293 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1294 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1295 }
1296 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1297 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1298 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001299 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001300 } else {
1301 SGSN_SIG[sgsn_idx].send(pdu_tx);
1302 }
1303 return pdu_rx;
1304}
1305
1306/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1307 * specified PCU index */
1308private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1309 boolean use_sig := false,integer pcu_idx := 0)
1310runs on BSSGP_ConnHdlr {
1311 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001312 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001313 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1314 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1315 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1316 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1317 timer T := 2.0;
1318 T.start;
1319 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001320 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001321 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001322 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001323 repeat;
1324 }
1325 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1326 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1327 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001328 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001329 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001330 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001331 repeat;
1332 }
Harald Welte158becf2020-12-09 12:32:32 +01001333 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001334 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1335 }
Harald Welte158becf2020-12-09 12:32:32 +01001336 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001337 setverdict(fail, "Paging received on unexpected BVC");
1338 }
1339 [] any from PCU_SIG.receive(exp_rx) {
1340 setverdict(fail, "Paging received on unexpected BVC");
1341 }
Harald Welte158becf2020-12-09 12:32:32 +01001342 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001343 setverdict(fail, "Different Paging than expected received PTP BVC");
1344 }
1345 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1346 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1347 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001348 [not test_done] T.timeout {
1349 setverdict(fail, "Timeout waiting for paging");
1350 }
1351 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001352 }
1353}
1354
Harald Welte7462a592020-11-23 22:07:07 +01001355/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1356private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1357 boolean use_sig := false)
1358runs on BSSGP_ConnHdlr {
1359 var template (present) PDU_BSSGP exp_rx;
1360 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1361 /* Expect paging to propagate to no BSS */
1362 timer T := 2.0;
1363 T.start;
1364 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001365 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001366 setverdict(fail, "Paging received on unexpected BVC");
1367 }
1368 [] any from PCU_SIG.receive(exp_rx) {
1369 setverdict(fail, "Paging received on unexpected BVC");
1370 }
Harald Welte158becf2020-12-09 12:32:32 +01001371 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001372 setverdict(fail, "Different Paging received on PTP BVC");
1373 }
1374 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1375 setverdict(fail, "Different Paging received on SIGNALING BVC");
1376 }
1377 [] T.timeout {
1378 setverdict(pass);
1379 }
1380 }
1381}
1382
Harald Welte0e188242020-11-22 21:46:48 +01001383private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1384{
1385 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1386 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1387 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1388}
1389testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001390 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001391 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001392 f_cleanup();
1393}
1394
1395/* PS-PAGING on PTP-BVC for Location Area */
1396private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1397{
1398 var template (present) PDU_BSSGP exp_rx;
1399 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1400 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1401 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1402}
1403testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001404 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001405 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001406 f_cleanup();
1407}
1408
Harald Welte7462a592020-11-23 22:07:07 +01001409/* PS-PAGING on PTP-BVC for unknown Location Area */
1410private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1411{
1412 var GSM_Types.LocationAreaIdentification unknown_la := {
1413 mcc_mnc := '567F99'H,
1414 lac := 33333
1415 };
1416 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1417 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1418}
1419testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001420 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001421 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001422 f_cleanup();
1423}
1424
Harald Welte0e188242020-11-22 21:46:48 +01001425/* PS-PAGING on PTP-BVC for Routeing Area */
1426private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1427{
1428 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1429 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1430 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1431}
1432testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001433 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001434 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001435 f_cleanup();
1436}
1437
Harald Welte7462a592020-11-23 22:07:07 +01001438/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1439private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1440{
1441 var RoutingAreaIdentification unknown_ra := {
1442 lai := {
1443 mcc_mnc := '567F99'H,
1444 lac := 33333
1445 },
1446 rac := 254
1447 };
1448 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1449 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1450}
1451testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001452 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001453 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001454 f_cleanup();
1455}
1456
Harald Welte0e188242020-11-22 21:46:48 +01001457/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1458private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1459{
1460 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1461 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1462}
1463testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001464 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001465 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001466 f_cleanup();
1467}
1468
Harald Welteb5a04aa2021-01-16 13:04:40 +01001469
1470/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1471testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1472 f_init();
1473 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1474 f_cleanup();
1475}
1476
Harald Weltecf200072021-01-16 15:20:46 +01001477/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1478testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1479 f_init();
1480 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1481 f_cleanup();
1482}
1483
1484/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1485private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1486{
1487 /* first send the PS-PAGING from SGSN -> PCU */
1488 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1489 /* then simulate the PS-PAGING-REJECT from the PCU */
1490 f_send_paging_ps_rej(use_sig:=false);
1491}
1492testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1493 f_init();
1494 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1495 f_cleanup();
1496}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001497
Harald Welte7462a592020-11-23 22:07:07 +01001498/* PS-PAGING on PTP-BVC for unknown BVCI */
1499private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1500{
1501 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1502 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1503}
1504testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001505 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001506 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001507 f_cleanup();
1508}
1509
Harald Welte7595d562021-01-16 19:09:20 +01001510/* DUMMY PAGING PS on PTP BVC */
1511private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1512{
1513 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1514 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1515 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1516 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1517}
1518testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1519 f_init();
1520 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1521 f_cleanup();
1522}
1523
Harald Welte0e188242020-11-22 21:46:48 +01001524/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1525private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1526runs on BSSGP_ConnHdlr {
1527[] PCU_SIG[pcu_idx].receive(exp_rx) {
1528 if (ro_integer_contains(roi, pcu_idx)) {
1529 setverdict(fail, "Received multiple paging on same SIG BVC");
1530 }
1531 roi := roi & { pcu_idx };
1532 repeat;
1533 }
Harald Welte158becf2020-12-09 12:32:32 +01001534[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001535 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1536 }
1537[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1538 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1539 }
Harald Welte158becf2020-12-09 12:32:32 +01001540[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001541 setverdict(fail, "Different Paging than expected received PTP BVC");
1542 }
1543}
1544
1545type record of default ro_default;
1546
1547/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1548private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1549 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1550{
1551 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001552 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001553
1554 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1555 var ro_default defaults := {};
1556 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1557 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1558 defaults := defaults & { d };
1559 }
1560 f_sleep(2.0);
1561 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1562 deactivate(defaults[i]);
1563 }
1564 log("Paging received on PCU ", g_roi);
1565
1566 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1567 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1568 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1569 if (exp_on_i and not rx_on_i) {
1570 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1571 }
1572 if (not exp_on_i and rx_on_i) {
1573 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1574 }
1575 }
1576 setverdict(pass);
1577}
1578
Harald Weltecf200072021-01-16 15:20:46 +01001579/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1580private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1581{
1582 var template (value) PDU_BSSGP pdu_tx;
1583 var template (present) PDU_BSSGP exp_rx;
1584 var PDU_BSSGP pdu_rx;
1585 timer T := 5.0;
1586 var template (omit) GsmTmsi tmsi_int := omit;
1587
1588 if (ispresent(g_pars.p_tmsi)) {
1589 tmsi_int := oct2int(g_pars.p_tmsi);
1590 }
1591
1592 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1593 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1594
1595 if (use_sig) {
1596 PCU_SIG[pcu_idx].send(pdu_tx);
1597 } else {
1598 PCU_PTP[pcu_idx].send(pdu_tx);
1599 }
1600 T.start;
1601 alt {
1602 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1603 setverdict(pass);
1604 }
1605 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1606 setverdict(fail, "Unexpected PDU on SGSN");
1607 }
1608 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1609 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1610 }
1611 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1612 setverdict(pass);
1613 }
1614 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1615 setverdict(fail, "Unexpected PDU on SGSN");
1616 }
1617 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1618 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1619 }
1620 [] T.timeout {
1621 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1622 }
1623 }
1624}
1625
Harald Welte0e188242020-11-22 21:46:48 +01001626/* PS-PAGING on SIG-BVC for BSS Area */
1627private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1628{
1629 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001630 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001631}
1632testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001633 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001634 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001635 f_cleanup();
1636}
1637
1638/* PS-PAGING on SIG-BVC for Location Area */
1639private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1640{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001641 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001642 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, {0, 1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001643 /* Reset state */
1644 g_roi := {};
1645 /* Make LAC (13300) available on pcu index 2 */
1646 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001647 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001648}
1649testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001650 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001651 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001652 f_cleanup();
1653}
1654
Harald Welte7462a592020-11-23 22:07:07 +01001655/* PS-PAGING on SIG-BVC for unknown Location Area */
1656private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1657{
1658 var GSM_Types.LocationAreaIdentification unknown_la := {
1659 mcc_mnc := '567F99'H,
1660 lac := 33333
1661 };
1662 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1663}
1664testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001665 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001666 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001667 f_cleanup();
1668}
1669
Harald Welte0e188242020-11-22 21:46:48 +01001670/* PS-PAGING on SIG-BVC for Routeing Area */
1671private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1672{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001673 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001674 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001675 g_roi := {};
1676 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001677 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001678 g_roi := {};
1679 /* PCU index 2 has two matching BVCs with the RA ID */
1680 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001681 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001682}
1683testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001684 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001685 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001686 f_cleanup();
1687}
1688
Harald Welte7462a592020-11-23 22:07:07 +01001689/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1690private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1691{
1692 var RoutingAreaIdentification unknown_ra := {
1693 lai := {
1694 mcc_mnc := '567F99'H,
1695 lac := 33333
1696 },
1697 rac := 254
1698 };
1699 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1700}
1701testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001702 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001703 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001704 f_cleanup();
1705}
1706
Harald Welte0e188242020-11-22 21:46:48 +01001707/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1708private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1709{
Daniel Willmann43320442021-01-17 14:07:05 +01001710 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Welte0e188242020-11-22 21:46:48 +01001711}
1712testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001713 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001714 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001715 f_cleanup();
1716}
1717
Harald Welteb5a04aa2021-01-16 13:04:40 +01001718/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1719testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1720 f_init();
1721 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1722 f_cleanup();
1723}
1724
Harald Weltecf200072021-01-16 15:20:46 +01001725/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1726private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1727{
1728 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001729 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Weltecf200072021-01-16 15:20:46 +01001730 /* then simulate the PS-PAGING-REJECT from the PCU */
1731 f_send_paging_ps_rej(use_sig:=true);
1732
1733}
1734testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1735 f_init();
1736 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1737 f_cleanup();
1738}
1739
1740/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1741testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1742 f_init();
1743 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1744 f_cleanup();
1745}
1746
Harald Welte7462a592020-11-23 22:07:07 +01001747/* PS-PAGING on SIG-BVC for unknown BVCI */
1748private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1749{
1750 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1751}
1752testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001753 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001754 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001755 f_cleanup();
1756}
1757
Harald Welte7595d562021-01-16 19:09:20 +01001758/* DUMMY PAGING PS on SIG BVC */
1759private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1760{
1761 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1762 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1763 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1764 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1765}
1766testcase TC_dummy_paging_ps_sig() runs on test_CT {
1767 f_init();
1768 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1769 f_cleanup();
1770}
1771
Harald Welte7462a592020-11-23 22:07:07 +01001772
Harald Welte0e188242020-11-22 21:46:48 +01001773
1774/***********************************************************************
1775 * PAGING CS procedure
1776 ***********************************************************************/
1777
1778private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1779 boolean use_sig := false)
1780runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1781 var template (value) PDU_BSSGP pdu_tx;
1782 var template (present) PDU_BSSGP pdu_rx;
1783 /* we always specify '0' as BVCI in the templates below, as we override it with
1784 * 'p4' later anyway */
1785 pdu_rx := tr_BSSGP_CS_PAGING(0);
1786 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1787 if (ispresent(g_pars.p_tmsi)) {
1788 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1789 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1790 } else {
1791 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1792 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1793 }
1794 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1795 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1796 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001797 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001798 } else {
1799 SGSN_SIG[sgsn_idx].send(pdu_tx);
1800 }
1801 return pdu_rx;
1802}
1803
1804/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1805 * specified PCU index */
1806private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1807 boolean use_sig := false,integer pcu_idx := 0)
1808runs on BSSGP_ConnHdlr {
1809 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001810 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001811 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1812 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1813 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1814 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1815 timer T := 2.0;
1816 T.start;
1817 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001818 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001819 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001820 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001821 repeat;
1822 }
1823 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1824 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1825 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001826 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001827 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001828 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001829 repeat;
1830 }
Harald Welte158becf2020-12-09 12:32:32 +01001831 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001832 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1833 }
Harald Welte158becf2020-12-09 12:32:32 +01001834 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001835 setverdict(fail, "Paging received on unexpected BVC");
1836 }
1837 [] any from PCU_SIG.receive(exp_rx) {
1838 setverdict(fail, "Paging received on unexpected BVC");
1839 }
Harald Welte158becf2020-12-09 12:32:32 +01001840 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001841 setverdict(fail, "Different Paging than expected received PTP BVC");
1842 }
1843 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1844 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1845 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001846 [not test_done] T.timeout {
1847 setverdict(fail, "Timeout while waiting for paging")
1848 }
1849 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001850 }
1851}
1852
Harald Welte7462a592020-11-23 22:07:07 +01001853/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1854private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1855 boolean use_sig := false)
1856runs on BSSGP_ConnHdlr {
1857 var template (present) PDU_BSSGP exp_rx;
1858 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1859 /* Expect paging to propagate to no BSS */
1860 timer T := 2.0;
1861 T.start;
1862 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001863 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001864 setverdict(fail, "Paging received on unexpected BVC");
1865 }
1866 [] any from PCU_SIG.receive(exp_rx) {
1867 setverdict(fail, "Paging received on unexpected BVC");
1868 }
Harald Welte158becf2020-12-09 12:32:32 +01001869 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001870 setverdict(fail, "Different Paging received on PTP BVC");
1871 }
1872 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1873 setverdict(fail, "Different Paging received on SIGNALING BVC");
1874 }
1875 [] T.timeout {
1876 setverdict(pass);
1877 }
1878 }
1879}
1880
Harald Welte0e188242020-11-22 21:46:48 +01001881private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1882{
1883 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1884 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1885 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1886}
1887testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001888 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001889 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01001890 f_cleanup();
1891}
1892
1893/* CS-PAGING on PTP-BVC for Location Area */
1894private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1895{
1896 var template (present) PDU_BSSGP exp_rx;
1897 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1898 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1899 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1900}
1901testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001902 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001903 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01001904 f_cleanup();
1905}
1906
Harald Welte7462a592020-11-23 22:07:07 +01001907/* CS-PAGING on PTP-BVC for unknown Location Area */
1908private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1909{
1910 var GSM_Types.LocationAreaIdentification unknown_la := {
1911 mcc_mnc := '567F99'H,
1912 lac := 33333
1913 };
1914 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1915 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1916}
1917testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001918 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001919 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001920 f_cleanup();
1921}
1922
Harald Welte0e188242020-11-22 21:46:48 +01001923/* CS-PAGING on PTP-BVC for Routeing Area */
1924private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1925{
1926 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1927 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1928 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1929}
1930testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001931 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001932 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01001933 f_cleanup();
1934}
1935
Harald Welte7462a592020-11-23 22:07:07 +01001936/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1937private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1938{
1939 var RoutingAreaIdentification unknown_ra := {
1940 lai := {
1941 mcc_mnc := '567F99'H,
1942 lac := 33333
1943 },
1944 rac := 254
1945 };
1946 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1947 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1948}
1949testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001950 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001951 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001952 f_cleanup();
1953}
1954
Harald Welte0e188242020-11-22 21:46:48 +01001955/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1956private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1957{
1958 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1959 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1960}
1961testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001962 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001963 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01001964 f_cleanup();
1965}
1966
Harald Welte7462a592020-11-23 22:07:07 +01001967/* CS-PAGING on PTP-BVC for unknown BVCI */
1968private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1969{
1970 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1971 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1972}
1973testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001974 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001975 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001976 f_cleanup();
1977}
1978
Harald Welte0e188242020-11-22 21:46:48 +01001979/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1980private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1981 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1982{
1983 var template (present) PDU_BSSGP exp_rx;
1984 exp_rx := f_send_paging_cs(p4, 0, true);
1985
1986 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1987 var ro_default defaults := {};
1988 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1989 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1990 defaults := defaults & { d };
1991 }
1992 f_sleep(2.0);
1993 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1994 deactivate(defaults[i]);
1995 }
1996 log("Paging received on PCU ", g_roi);
1997
1998 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1999 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2000 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2001 if (exp_on_i and not rx_on_i) {
2002 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2003 }
2004 if (not exp_on_i and rx_on_i) {
2005 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2006 }
2007 }
2008 setverdict(pass);
2009}
2010
2011/* CS-PAGING on SIG-BVC for BSS Area */
2012private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2013{
2014 /* we expect the paging to arrive on all three NSE */
2015 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2016}
2017testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002018 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002019 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002020 f_cleanup();
2021}
2022
2023/* CS-PAGING on SIG-BVC for Location Area */
2024private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2025{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002026 /* The first LAC (13135) is shared by all three NSEs */
2027 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2028 /* Reset state */
2029 g_roi := {};
2030 /* Make LAC (13300) available on pcu index 2 */
2031 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2032 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 +01002033}
2034testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002035 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002036 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002037 f_cleanup();
2038}
2039
Harald Welte7462a592020-11-23 22:07:07 +01002040/* CS-PAGING on SIG-BVC for unknown Location Area */
2041private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2042{
2043 var GSM_Types.LocationAreaIdentification unknown_la := {
2044 mcc_mnc := '567F99'H,
2045 lac := 33333
2046 };
2047 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2048}
2049testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002050 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002051 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002052 f_cleanup();
2053}
2054
Harald Welte0e188242020-11-22 21:46:48 +01002055/* CS-PAGING on SIG-BVC for Routeing Area */
2056private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2057{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002058 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002059 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 +01002060 g_roi := {};
2061 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2062 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2063 g_roi := {};
2064 /* PCU index 2 has two matching BVCs with the RA ID */
2065 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2066 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 +01002067}
2068testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002069 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002070 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002071 f_cleanup();
2072}
2073
Harald Welte7462a592020-11-23 22:07:07 +01002074/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2075private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2076{
2077 var RoutingAreaIdentification unknown_ra := {
2078 lai := {
2079 mcc_mnc := '567F99'H,
2080 lac := 33333
2081 },
2082 rac := 254
2083 };
2084 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2085}
2086testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002087 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002088 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002089 f_cleanup();
2090}
2091
Harald Welte0e188242020-11-22 21:46:48 +01002092/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2093private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2094{
2095 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2096}
2097testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002098 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002099 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002100 f_cleanup();
2101}
2102
Harald Welte7462a592020-11-23 22:07:07 +01002103/* CS-PAGING on SIG-BVC for unknown BVCI */
2104private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2105{
2106 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2107}
2108testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002109 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002110 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002111 f_cleanup();
2112}
2113
Harald Welte4f91c3b2020-12-09 12:25:51 +01002114/***********************************************************************
2115 * FLUSH-LL procedure
2116 ***********************************************************************/
2117
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002118private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2119 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2120 var integer i;
2121 for (i := 0; i < 10; i := i+1) {
2122 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2123 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2124 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2125
2126 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2127
2128 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2129 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2130 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2131
2132 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2133 }
2134 setverdict(pass);
2135}
2136testcase TC_flush_ll() runs on test_CT
2137{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002138 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002139 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002140 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002141 f_cleanup();
2142}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002143
Harald Welte4f91c3b2020-12-09 12:25:51 +01002144/***********************************************************************
2145 * SGSN-INVOKE-TRACE procedure
2146 ***********************************************************************/
2147
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002148private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2149runs on GlobalTest_CT {
2150[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2151 if (ro_integer_contains(roi, pcu_idx)) {
2152 setverdict(fail, "Received multiple on same SIG BVC");
2153 }
2154 roi := roi & { pcu_idx };
2155 repeat;
2156 }
2157}
2158/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2159testcase TC_trace() runs on GlobalTest_CT
2160{
2161 var BSSGP_ConnHdlr vc_conn;
2162 f_init();
2163 f_global_init();
2164
2165 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2166 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2167
2168 var ro_default defaults := {};
2169 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2170 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2171 }
2172 G_SGSN[0].send(pdu_tx);
2173 f_sleep(2.0);
2174 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2175 deactivate(defaults[i]);
2176 }
2177
2178 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2179 if (not ro_integer_contains(g_roi, i)) {
2180 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2181 }
2182 }
2183 setverdict(pass);
2184
2185 f_cleanup();
2186}
2187
Harald Welte4f91c3b2020-12-09 12:25:51 +01002188/***********************************************************************
2189 * LLC-DISCARDED procedure
2190 ***********************************************************************/
2191
Harald Weltec0351d12020-11-27 22:49:02 +01002192private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2193 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2194
2195 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2196 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2197 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2198
2199 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2200
2201 setverdict(pass);
2202}
2203/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2204testcase TC_llc_discarded() runs on test_CT
2205{
Harald Weltec0351d12020-11-27 22:49:02 +01002206 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002207 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002208 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002209 f_cleanup();
2210}
2211
Harald Welte4f91c3b2020-12-09 12:25:51 +01002212/***********************************************************************
2213 * OVERLOAD procedure
2214 ***********************************************************************/
2215
Harald Weltef20af412020-11-28 16:11:11 +01002216/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2217testcase TC_overload() runs on GlobalTest_CT
2218{
2219 f_init();
2220 f_global_init();
2221
2222 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2223 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2224
2225 var ro_default defaults := {};
2226 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2227 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2228 }
2229 G_SGSN[0].send(pdu_tx);
2230 f_sleep(2.0);
2231 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2232 deactivate(defaults[i]);
2233 }
2234
2235 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2236 if (not ro_integer_contains(g_roi, i)) {
2237 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2238 }
2239 }
2240 setverdict(pass);
2241
2242 f_cleanup();
2243}
2244
Harald Welte4f91c3b2020-12-09 12:25:51 +01002245/***********************************************************************
2246 * BVC-BLOCK / BVC-UNBLOCK procedure
2247 ***********************************************************************/
2248
Harald Welte239aa502020-11-24 23:14:20 +01002249private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2250{
2251 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2252 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2253 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2254
2255 SGSN_MGMT.clear;
2256 PCU_MGMT.clear;
2257
2258 /* block the PTP BVC from the PCU side */
2259 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2260 /* expect state on both PCU and SGSN side to change */
2261 interleave {
2262 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2263 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2264 }
2265 setverdict(pass);
2266}
2267testcase TC_bvc_block_ptp() runs on test_CT
2268{
2269 f_init();
2270 f_sleep(1.0);
2271 f_block_ptp_bvc_from_pcu(0, 0);
2272 f_cleanup();
2273}
2274
2275private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2276{
2277 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2278 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2279 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2280
2281 SGSN_MGMT.clear;
2282 PCU_MGMT.clear;
2283
2284 /* block the PTP BVC from the PCU side */
2285 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2286 /* expect state on both PCU and SGSN side to change */
2287 interleave {
2288 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2289 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2290 }
2291 setverdict(pass);
2292}
2293testcase TC_bvc_unblock_ptp() runs on test_CT
2294{
2295 f_init();
2296 f_sleep(1.0);
2297 f_block_ptp_bvc_from_pcu(0, 0);
2298 f_sleep(1.0);
2299 f_unblock_ptp_bvc_from_pcu(0, 0);
2300 f_cleanup();
2301}
2302
Harald Welte4f91c3b2020-12-09 12:25:51 +01002303/***********************************************************************
2304 * BVC-RESET procedure
2305 ***********************************************************************/
2306
Harald Welte60a8ec72020-11-25 17:12:53 +01002307private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2308[] pt.receive(BssgpStatusIndication:?) { repeat; }
2309}
2310private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2311 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2312 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2313 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2314 }
2315 }
2316 return null;
2317}
2318private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2319{
2320 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2321 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2322 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2323 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2324 var default d;
2325
2326 SGSN_MGMT.clear;
2327 PCU_MGMT.clear;
2328
2329 /* block the PTP BVC from the PCU side */
2330 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2331 /* expect state on both PCU and SGSN side to change */
2332 d := activate(as_ignore_status(SGSN_MGMT));
2333 interleave {
2334 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2335 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2336 }
2337 deactivate(d);
2338 setverdict(pass);
2339}
2340/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2341testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2342{
2343 f_init();
2344 f_sleep(3.0);
2345 f_reset_ptp_bvc_from_pcu(0, 0);
2346 f_cleanup();
2347}
2348
Harald Welte16786e92020-11-27 19:11:56 +01002349private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2350runs on test_CT {
2351 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2352 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2353 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002354 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002355 }
2356}
2357/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2358testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2359
2360 f_init();
2361 f_sleep(3.0);
2362
2363 /* Start BVC-RESET procedure for BVCI=0 */
2364 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2365
2366 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2367 var ro_default defaults := {};
2368 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2369 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2370 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2371 defaults := defaults & { d };
2372 }
2373
2374 timer T := 3.0;
2375 T.start;
2376 alt {
2377 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2378 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2379 }
2380 [] T.timeout;
2381 }
2382
2383 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2384 deactivate(defaults[i]);
2385 }
2386
2387 /* check if BVC-block was received on all expected BVC */
2388 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2389 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2390 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2391 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2392 }
2393 }
2394
2395 /* check if BVC-block was not received on any unexpected BVC is not required as
2396 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002397 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002398 f_cleanup();
2399}
2400
Harald Welte60a8ec72020-11-25 17:12:53 +01002401private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2402{
2403 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2404 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2405 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2406 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2407 var default d;
2408
2409 SGSN_MGMT.clear;
2410 PCU_MGMT.clear;
2411
2412 /* block the PTP BVC from the PCU side */
2413 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2414 /* expect state on both PCU and SGSN side to change */
2415 d := activate(as_ignore_status(PCU_MGMT));
2416 interleave {
2417 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2418 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2419 }
2420 deactivate(d);
2421 setverdict(pass);
2422}
2423/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2424testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2425{
2426 f_init();
2427 f_sleep(3.0);
2428 f_reset_ptp_bvc_from_sgsn(0, 0);
2429 f_cleanup();
2430}
2431
Daniel Willmannef7015f2021-01-08 00:43:56 +01002432private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2433 [] pt.receive {repeat; }
2434}
2435
Harald Welte16786e92020-11-27 19:11:56 +01002436private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2437runs on test_CT {
2438 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2439 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2440 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002441 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002442 }
2443}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002444
Harald Welte16786e92020-11-27 19:11:56 +01002445/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2446testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2447
2448 f_init();
2449 f_sleep(3.0);
2450
Daniel Willmannef7015f2021-01-08 00:43:56 +01002451 SGSN_MGMT.clear;
2452 PCU_MGMT.clear;
2453
Harald Welte16786e92020-11-27 19:11:56 +01002454 /* Start BVC-RESET procedure for BVCI=0 */
2455 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2456
Daniel Willmannef7015f2021-01-08 00:43:56 +01002457 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2458 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2459 * the port and a different message sits at the front we wait forever and fail the test.
2460 */
2461 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2462
Harald Welte16786e92020-11-27 19:11:56 +01002463 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002464 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2465 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2466 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2467 defaults := defaults & { d };
2468 }
2469
2470 f_sleep(3.0);
2471
2472 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2473 deactivate(defaults[i]);
2474 }
2475
2476 /* check if BVC-block was received on all expected BVC */
2477 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2478 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2479 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2480 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2481 }
2482 }
2483
2484 /* check if BVC-block was not received on any unexpected BVC is not required as
2485 * such a message would basically run into 'no matching clause' */
2486
2487 f_cleanup();
2488}
2489
Harald Welte299aa482020-12-09 15:10:55 +01002490/***********************************************************************
2491 * FLOW-CONTROL-BVC procedure
2492 ***********************************************************************/
2493
2494private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2495 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2496runs on GlobalTest_CT {
2497 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2498 roi := roi & { sgsn_idx };
2499 if (ispresent(tx_reply)) {
2500 G_SGSN[sgsn_idx].send(tx_reply);
2501 }
Harald Welte5fb01742021-01-15 21:07:52 +01002502 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002503 }
2504}
2505/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2506testcase TC_fc_bvc() runs on GlobalTest_CT
2507{
2508 f_init();
2509 f_global_init_ptp();
2510
2511 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2512 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2513 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2514 var template (omit) PDU_BSSGP ack_tx :=
2515 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2516
2517 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2518 G_PCU[0].send(pdu_tx);
2519
2520 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2521 var ro_default defaults := {};
2522 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2523 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2524 defaults := defaults & { d };
2525 }
2526
2527 f_sleep(3.0);
2528
2529 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2530 deactivate(defaults[i]);
2531 }
2532
2533 /* check if BVC-block was received on all expected BVC */
2534 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2535 if (not ro_integer_contains(g_roi, i)) {
2536 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2537 }
2538 }
2539
2540 /* Expect ACK on PCU side */
2541 G_PCU[0].receive(ack_tx);
2542
2543 setverdict(pass);
2544
2545 f_cleanup();
2546}
2547
Harald Weltecc3894b2020-12-09 16:50:12 +01002548/***********************************************************************
2549 * FLOW-CONTROL-MS procedure
2550 ***********************************************************************/
2551
2552private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2553 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2554
2555 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2556 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2557 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2558 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2559
2560 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2561 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2562
2563 setverdict(pass);
2564}
2565/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2566testcase TC_fc_ms() runs on test_CT
2567{
Harald Weltecc3894b2020-12-09 16:50:12 +01002568 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002569 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002570 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002571 f_cleanup();
2572}
2573
Harald Welted6f89812021-01-16 18:57:49 +01002574/***********************************************************************
2575 * MS-REGISTRATION ENQUIRY procedure
2576 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002577
Harald Welted6f89812021-01-16 18:57:49 +01002578private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2579{
2580 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2581 f_sgsn2pcu(ts_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), tr_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), use_sig := true);
2582}
2583testcase TC_ms_reg_enq() runs on test_CT
2584{
2585 f_init();
2586 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2587 f_cleanup();
2588}
Harald Welte299aa482020-12-09 15:10:55 +01002589
Harald Weltef86f1852021-01-16 21:56:17 +01002590/***********************************************************************
2591 * RIM (RAN Information Management)
2592 ***********************************************************************/
2593
2594/* Our tests here are rather synthetic, as they don't reflect normal message flows
2595 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2596 matter as gbproxy is not concerned with anything but the source / destination routing
2597 information */
2598
2599/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2600 one here of which we know it is not used among the [simulated] PCUs */
2601const BssgpCellId cell_id_sgsn := {
2602 ra_id := {
2603 lai := {
2604 mcc_mnc := c_mcc_mnc,
2605 lac := 65534
2606 },
2607 rac := 0
2608 },
2609 cell_id := 65533
2610};
2611
2612/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2613friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2614 integer pcu_idx := 0) runs on GlobalTest_CT {
2615 var PDU_BSSGP rx;
2616 timer T := 1.0;
2617
2618 RIM_PCU[pcu_idx].send(tx);
2619 T.start;
2620 alt {
2621 [] any from RIM_SGSN.receive(exp_rx) {
2622 setverdict(pass);
2623 }
2624 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2625 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2626 mtc.stop;
2627 }
2628 [] T.timeout {
2629 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2630 mtc.stop;
2631 }
2632 }
2633}
2634
2635/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2636friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2637 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2638 var PDU_BSSGP rx;
2639 timer T := 1.0;
2640
2641 RIM_SGSN[sgsn_idx].send(tx);
2642 T.start;
2643 alt {
2644 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2645 setverdict(pass);
2646 }
2647 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
2648 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
2649 mtc.stop;
2650 }
2651 [] T.timeout {
2652 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
2653 mtc.stop;
2654 }
2655 }
2656}
2657
2658/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2659friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2660 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2661 var integer rx_idx;
2662 var PDU_BSSGP rx;
2663 timer T := 1.0;
2664
2665 RIM_PCU[src_pcu_idx].send(tx);
2666 T.start;
2667 alt {
2668 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2669 setverdict(pass);
2670 }
2671 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2672 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2673 }
2674 [] any from RIM_SGSN.receive(exp_rx) {
2675 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2676 }
2677 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2678 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2679 mtc.stop;
2680 }
2681 [] T.timeout {
2682 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2683 mtc.stop;
2684 }
2685 }
2686}
2687
2688
2689type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2690
2691/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2692 each SGSN */
2693private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2694{
2695 var integer sgsn_idx, pcu_idx, bvc_idx;
2696 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2697 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2698 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2699 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2700 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2701 }
2702 }
2703 }
2704}
2705
2706/* RAN-INFORMATION-REQUEST */
2707private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2708runs on GlobalTest_CT
2709{
2710 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2711 var template (value) RIM_Routing_Information ri_pcu;
2712 var template (value) RIM_Routing_Information ri_sgsn;
2713 var template (value) RAN_Information_Request_RIM_Container cont;
2714
2715 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2716 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2717 cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2718 ts_RIM_Sequence_Number(0),
2719 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2720 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2721 tr_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2722 pcu_idx);
2723 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2724 tr_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2725 sgsn_idx, pcu_idx);
2726}
2727testcase TC_rim_info_req() runs on GlobalTest_CT
2728{
2729 f_init();
2730 f_global_init();
2731 f_rim_iterator(refers(f_TC_rim_info_req));
2732 f_cleanup();
2733}
2734
2735/* RAN-INFORMATION */
2736private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2737runs on GlobalTest_CT
2738{
2739 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2740 var template (value) RIM_Routing_Information ri_pcu;
2741 var template (value) RIM_Routing_Information ri_sgsn;
2742 var template (value) RAN_Information_RIM_Container cont;
2743
2744 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2745 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2746 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2747 ts_RIM_Sequence_Number(0),
2748 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2749 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2750 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2751 pcu_idx);
2752 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2753 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2754 sgsn_idx, pcu_idx);
2755}
2756testcase TC_rim_info() runs on GlobalTest_CT
2757{
2758 f_init();
2759 f_global_init();
2760 f_rim_iterator(refers(f_TC_rim_info));
2761 f_cleanup();
2762}
2763
2764/* RAN-INFORMATION-ACK */
2765private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2766runs on GlobalTest_CT
2767{
2768 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2769 var template (value) RIM_Routing_Information ri_pcu;
2770 var template (value) RIM_Routing_Information ri_sgsn;
2771 var template (value) RAN_Information_Ack_RIM_Container cont;
2772
2773 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2774 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2775 cont := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2776 ts_RIM_Sequence_Number(0));
2777 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2778 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2779 pcu_idx);
2780 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2781 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2782 sgsn_idx, pcu_idx);
2783}
2784testcase TC_rim_info_ack() runs on GlobalTest_CT
2785{
2786 f_init();
2787 f_global_init();
2788 f_rim_iterator(refers(f_TC_rim_info_ack));
2789 f_cleanup();
2790}
2791
2792/* RAN-INFORMATION-ERROR */
2793private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2794runs on GlobalTest_CT
2795{
2796 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2797 var template (value) RIM_Routing_Information ri_pcu;
2798 var template (value) RIM_Routing_Information ri_sgsn;
2799 var template (value) RAN_Information_Error_RIM_Container cont;
2800
2801 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2802 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2803 cont := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2804 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
2805 omit, valueof(t_BVC_UNBLOCK(23)));
2806 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2807 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2808 pcu_idx);
2809 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2810 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2811 sgsn_idx, pcu_idx);
2812}
2813testcase TC_rim_info_error() runs on GlobalTest_CT
2814{
2815 f_init();
2816 f_global_init();
2817 f_rim_iterator(refers(f_TC_rim_info_error));
2818 f_cleanup();
2819}
2820
2821/* RAN-INFORMATION-APPLICATION-ERROR */
2822private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2823runs on GlobalTest_CT
2824{
2825 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2826 var template (value) RIM_Routing_Information ri_pcu;
2827 var template (value) RIM_Routing_Information ri_sgsn;
2828 var template (value) Application_Error_Container app_cont;
2829 var template (value) RAN_Information_Application_Error_RIM_Container cont;
2830
2831 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2832 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2833 app_cont := tsu_Application_Error_Container_NACC(cell_id, 23,
2834 tsu_Application_Container_IE_NACC_req(cell_id));
2835 cont := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2836 ts_RIM_Sequence_Number(0),
2837 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
2838 omit, app_cont);
2839 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2840 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2841 pcu_idx);
2842 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2843 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2844 sgsn_idx, pcu_idx);
2845}
2846testcase TC_rim_info_app_error() runs on GlobalTest_CT
2847{
2848 f_init();
2849 f_global_init();
2850 f_rim_iterator(refers(f_TC_rim_info_app_error));
2851 f_cleanup();
2852}
2853
2854/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
2855private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
2856 integer dst_pcu_idx, integer dst_bvc_idx)
2857runs on GlobalTest_CT
2858{
2859 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
2860 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
2861 var template (value) RIM_Routing_Information ri_pcu_src;
2862 var template (value) RIM_Routing_Information ri_pcu_dst;
2863 var template (value) RAN_Information_RIM_Container cont;
2864
2865 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
2866 dst_pcu_idx, "][", dst_bvc_idx, "]");
2867
2868 ri_pcu_src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
2869 t_RIM_Routing_Address_cid(cell_id_src));
2870 ri_pcu_dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
2871 t_RIM_Routing_Address_cid(cell_id_dst));
2872 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2873 ts_RIM_Sequence_Number(0),
2874 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2875 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
2876 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
2877 src_pcu_idx, dst_pcu_idx);
2878}
2879testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
2880{
2881 var integer src_pcu_idx, dst_pcu_idx;
2882 var integer src_bvc_idx, dst_bvc_idx;
2883 f_init();
2884 f_global_init();
2885
2886 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
2887 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
2888 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
2889 if (dst_pcu_idx == src_pcu_idx) {
2890 continue;
2891 }
2892
2893 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
2894dst_bvc_idx := dst_bvc_idx + 1) {
2895 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
2896 }
2897 }
2898 }
2899 }
2900
2901 f_cleanup();
2902}
2903
2904
Daniel Willmann423d8f42020-09-08 18:58:22 +02002905control {
2906 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002907 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002908 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002909 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002910 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002911 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002912 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002913 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002914 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002915 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002916 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002917 execute( TC_bvc_block_ptp() );
2918 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002919 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002920 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002921 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002922 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002923 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002924 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2925 execute( TC_load_sharing_dl() );
2926 }
Harald Welte0e188242020-11-22 21:46:48 +01002927
2928 /* PAGING-PS over PTP BVC */
2929 execute( TC_paging_ps_ptp_bss() );
2930 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002931 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002932 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002933 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002934 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01002935 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01002936 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01002937 execute( TC_paging_ps_reject_ptp_bvci() );
2938 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01002939 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01002940
2941 /* PAGING-PS over SIG BVC */
2942 execute( TC_paging_ps_sig_bss() );
2943 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002944 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002945 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002946 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002947 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01002948 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01002949 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01002950 execute( TC_paging_ps_reject_sig_bvci() );
2951 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01002952 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01002953
2954 /* PAGING-CS over PTP BVC */
2955 execute( TC_paging_cs_ptp_bss() );
2956 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002957 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002958 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002959 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002960 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002961 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002962
2963 /* PAGING-CS over SIG BVC */
2964 execute( TC_paging_cs_sig_bss() );
2965 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002966 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002967 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002968 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002969 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002970 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002971
Harald Weltef86f1852021-01-16 21:56:17 +01002972 /* RAN Information Management */
2973 execute( TC_rim_info_req() );
2974 execute( TC_rim_info() );
2975 execute( TC_rim_info_ack() );
2976 execute( TC_rim_info_error() );
2977 execute( TC_rim_info_app_error() );
2978 execute( TC_rim_info_pcu2pcu() );
2979
Harald Welte0e188242020-11-22 21:46:48 +01002980
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002981 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002982 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002983 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01002984 execute( TC_ms_reg_enq() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002985}
2986
2987
2988}