blob: 9168fa346a4b94ef9f1a1df35ae52b863f65cf2f [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010017import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020018import from GSM_Types all;
19import from Native_Functions all;
20import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
24import from SCCPasp_Types all;
25import from Osmocom_Gb_Types all;
26
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
36import from LLC_Types all;
37import from LLC_Templates all;
38
39import from GSM_RR_Types all;
40
Harald Welte6d63f742020-11-15 19:44:04 +010041/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
42const BcdMccMnc c_mcc_mnc := '262F42'H;
43
Harald Welte0d5fceb2020-11-29 16:04:07 +010044/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
45const integer max_fr_info_size := 1600;
46
Daniel Willmann423d8f42020-09-08 18:58:22 +020047modulepar {
Harald Welte77218d02021-01-15 19:59:15 +010048 /* NRI bit-length. 0 for no pooling */
49 integer mp_nri_bitlength := 5;
50 roro_integer mp_sgsn_nri := {
51 { 3 }, /* list of NRIs of first SGSN */
52 { 4 } /* list of NRIs of second SGSN */
53 };
Harald Weltef6e59b02020-12-08 08:29:09 +010054 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010055 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010056 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020057 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 nsei := 101,
59 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010060 handle_sns := false,
61 nsvc := {
62 {
63 provider := {
64 ip := {
65 address_family := AF_INET,
66 local_udp_port := 7777,
67 local_ip := "127.0.0.1",
68 remote_udp_port := 23000,
69 remote_ip := "127.0.0.1"
70 }
71 },
72 nsvci := 101
73 }
74 }
Harald Welteb978ed62020-12-12 14:01:11 +010075 }, {
76 nsei := 102,
77 role_sgsn := true,
78 handle_sns := false,
79 nsvc := {
80 {
81 provider := {
82 ip := {
83 address_family := AF_INET,
84 local_udp_port := 8888,
85 local_ip := "127.0.0.1",
86 remote_udp_port := 23000,
87 remote_ip := "127.0.0.1"
88 }
89 },
90 nsvci := 102
91 }
92 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020093 }
94 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010095 /* BSS NSEI start at 2000 + x
96 * NSVCI start from value of NSEI + 100
97 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010098 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020099 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100100 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200101 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100102 handle_sns := false,
103 nsvc := {
104 {
105 provider := {
106 ip := {
107 address_family := AF_INET,
108 local_udp_port := 21010,
109 local_ip := "127.0.0.1",
110 remote_udp_port := 23000,
111 remote_ip := "127.0.0.1"
112 }
113 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100114 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100115 }
116 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200117 },
118 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100119 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200120 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100121 handle_sns := false,
122 nsvc := {
123 {
124 provider := {
125 ip := {
126 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100128 local_ip := "127.0.0.1",
129 remote_udp_port := 23000,
130 remote_ip := "127.0.0.1"
131 }
132 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100133 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100134 }
135 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200136 },
137 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100138 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200139 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100140 handle_sns := false,
141 nsvc := {
142 {
143 provider := {
144 ip := {
145 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100146 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100147 local_ip := "127.0.0.1",
148 remote_udp_port := 23000,
149 remote_ip := "127.0.0.1"
150 }
151 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100152 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100153 }
154 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200155 }
156 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100157 /* BVCI are NSEI*10 + x
158 * The first NSE only has one BVC, the second one 2 and so on
159 * The Cell ID is BVCI + 10000
160 * LAC/RAC are configured in such a way that:
161 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
162 * LAC 13300 is present twice in NSE(2003)
163 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
164 * RAI 13300-0 is present twice in NSE(2003)
165 */
Harald Welte6d63f742020-11-15 19:44:04 +0100166 BssgpConfigs mp_gbconfigs := {
167 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100168 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100169 sgsn_role := false,
170 bvc := {
171 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100172 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100173 cell_id := {
174 ra_id := {
175 lai := {
176 mcc_mnc := c_mcc_mnc,
177 lac := 13135
178 },
179 rac := 0
180 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100181 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100182 },
183 depth := BSSGP_DECODE_DEPTH_BSSGP,
184 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
185 }
186 }
187 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100188 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100189 sgsn_role := false,
190 bvc := {
191 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100192 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100193 cell_id := {
194 ra_id := {
195 lai := {
196 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100197 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100198 },
Harald Welte0e188242020-11-22 21:46:48 +0100199 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100200 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100201 cell_id := 30021
202 },
203 depth := BSSGP_DECODE_DEPTH_BSSGP,
204 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
205 },
206 {
207 bvci := 20022,
208 cell_id := {
209 ra_id := {
210 lai := {
211 mcc_mnc := c_mcc_mnc,
212 lac := 13135
213 },
214 rac := 2
215 },
216 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100217 },
218 depth := BSSGP_DECODE_DEPTH_BSSGP,
219 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
220 }
221 }
222 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100223 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100224 sgsn_role := false,
225 bvc := {
226 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100227 bvci := 20031,
228 cell_id := {
229 ra_id := {
230 lai := {
231 mcc_mnc := c_mcc_mnc,
232 lac := 13135
233 },
234 rac := 1
235 },
236 cell_id := 30031
237 },
238 depth := BSSGP_DECODE_DEPTH_BSSGP,
239 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
240 },
241 {
242 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100243 cell_id := {
244 ra_id := {
245 lai := {
246 mcc_mnc := c_mcc_mnc,
247 lac := 13300
248 },
249 rac := 0
250 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100251 cell_id := 30032
252 },
253 depth := BSSGP_DECODE_DEPTH_BSSGP,
254 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
255 },
256 {
257 bvci := 20033,
258 cell_id := {
259 ra_id := {
260 lai := {
261 mcc_mnc := c_mcc_mnc,
262 lac := 13300
263 },
264 rac := 0
265 },
266 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100267 },
268 depth := BSSGP_DECODE_DEPTH_BSSGP,
269 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
270 }
271 }
272 }
273 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200274};
275
Daniel Willmann423d8f42020-09-08 18:58:22 +0200276type record GbInstance {
277 NS_CT vc_NS,
278 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100279 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200280 BssgpConfig cfg
281};
Harald Welte67dc8c22020-11-17 18:32:29 +0100282type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200283
284const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100285type record of GbInstance GbInstances;
286type record of BssgpConfig BssgpConfigs;
287type record of NSConfiguration NSConfigurations;
288type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200289
Harald Welteb978ed62020-12-12 14:01:11 +0100290const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200291
292type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100293 var GbInstances g_pcu;
294 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200295
296 port BSSGP_CT_PROC_PT PROC;
297
Harald Weltefbae83f2020-11-15 23:25:55 +0100298 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
299 port BSSGP_BVC_MGMT_PT PCU_MGMT;
300
Daniel Willmann423d8f42020-09-08 18:58:22 +0200301 port TELNETasp_PT GBPVTY;
302
303 var boolean g_initialized := false;
304 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100305
306 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100307 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200308};
309
310type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100311 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100312 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200313 port BSSGP_PT PCU_SIG[NUM_PCU];
314 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100315 /* component reference to the component to which we're currently connected */
316 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100317 /* BSSGP BVC configuration of the component to which we're currently connected */
318 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100319
320 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100321 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200322 port BSSGP_PT SGSN_SIG[NUM_SGSN];
323 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100324 /* component reference to the component to which we're currently connected */
325 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200326
327 var BSSGP_ConnHdlrPars g_pars;
328 timer g_Tguard;
329 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100330
331 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200332}
333
334type record SGSN_ConnHdlrNetworkPars {
335 boolean expect_ptmsi,
336 boolean expect_auth,
337 boolean expect_ciph
338};
339
340type record BSSGP_ConnHdlrPars {
341 /* IMEI of the simulated ME */
342 hexstring imei,
343 /* IMSI of the simulated MS */
344 hexstring imsi,
345 /* MSISDN of the simulated MS (probably unused) */
346 hexstring msisdn,
347 /* P-TMSI allocated to the simulated MS */
348 OCT4 p_tmsi optional,
349 OCT3 p_tmsi_sig optional,
350 /* TLLI of the simulated MS */
351 OCT4 tlli,
352 OCT4 tlli_old optional,
353 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100354 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100355 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200356 float t_guard
357};
358
359private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
360 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
361 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
362
363 var RoutingAreaIdentificationV ret := {
364 mccDigit1 := mcc_mnc[0],
365 mccDigit2 := mcc_mnc[1],
366 mccDigit3 := mcc_mnc[2],
367 mncDigit3 := mcc_mnc[3],
368 mncDigit1 := mcc_mnc[4],
369 mncDigit2 := mcc_mnc[5],
370 lac := int2oct(cell_id.ra_id.lai.lac, 16),
371 rac := int2oct(cell_id.ra_id.rac, 8)
372 }
373 return ret;
374};
375
Harald Welte95339432020-12-02 18:50:52 +0100376private function f_fix_create_cb(inout BssgpConfig cfg)
377{
378 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
379 if (not isbound(cfg.bvc[i].create_cb)) {
380 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
381 }
382 }
383}
384
Daniel Willmann423d8f42020-09-08 18:58:22 +0200385private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100386 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
387 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
388 gb.vc_NS := NS_CT.create(ns_id);
389 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200390 /* connect lower end of BSSGP emulation with NS upper port */
391 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
392
Harald Welteb419d0e2020-11-16 16:45:05 +0100393 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
394 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200395
396 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100397 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200398 connect(self:PROC, gb.vc_BSSGP:PROC);
399 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
400 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100401 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100402 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200403 }
Harald Welteb978ed62020-12-12 14:01:11 +0100404 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100405 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200406}
407
408private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100409 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
410 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
411 gb.vc_NS := NS_CT.create(ns_id);
412 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200413 /* connect lower end of BSSGP emulation with NS upper port */
414 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
415
Harald Welteb419d0e2020-11-16 16:45:05 +0100416 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
417 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200418
419 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100420 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200421 connect(self:PROC, gb.vc_BSSGP:PROC);
422 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
423 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100424 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100425 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200426 }
Harald Welteb978ed62020-12-12 14:01:11 +0100427 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100428 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200429}
430
431
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100432private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
433 gb.vc_NS.stop;
434 gb.vc_BSSGP.stop;
435
436 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
437 gb.vc_BSSGP_BVC[i].stop;
438 }
439}
440
Daniel Willmann423d8f42020-09-08 18:58:22 +0200441private function f_init_vty() runs on test_CT {
442 map(self:GBPVTY, system:GBPVTY);
443 f_vty_set_prompts(GBPVTY);
444 f_vty_transceive(GBPVTY, "enable");
445}
446
Harald Weltefbae83f2020-11-15 23:25:55 +0100447type record of integer ro_integer;
448
449private function ro_integer_contains(ro_integer r, integer x) return boolean {
450 for (var integer j := 0; j < lengthof(r); j := j+1) {
451 if (r[j] == x) {
452 return true;
453 }
454 }
455 return false;
456}
457
Harald Welteb978ed62020-12-12 14:01:11 +0100458private type record of ro_integer roro_integer;
459
460/* count the number of unblocked BVCI for each SGSN NSE */
461private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
462runs on test_CT {
463 var BssgpStatusIndication bsi;
464 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
465 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
466 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
467 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
468 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
469 repeat;
470 }
471 }
472 }
473}
474
Harald Welte425d3762020-12-09 14:33:18 +0100475function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100476 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100477 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200478 var integer i;
479
480 if (g_initialized == true) {
481 return;
482 }
483 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200484
Harald Welte425d3762020-12-09 14:33:18 +0100485 g_Tguard.start(t_guard);
486 activate(as_gTguard(g_Tguard));
487
Harald Welteb978ed62020-12-12 14:01:11 +0100488 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100489 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
490 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100491 /* make sure all have a proper crate_cb, which cannot be specified in config file */
492 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100493 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100494 bvcs := bvcs & g_pcu[i].cfg.bvc;
495 }
496
497 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
498 g_sgsn[i].cfg := {
499 nsei := mp_nsconfig_sgsn[i].nsei,
500 sgsn_role := true,
501 bvc := bvcs
502 }
Harald Welte6d63f742020-11-15 19:44:04 +0100503 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200504
505 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100506 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100507 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100508 }
509 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
510 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
511 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
512 }
513
514 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100515 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100516 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200517 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100518 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100519 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100520 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100521
Harald Welteb978ed62020-12-12 14:01:11 +0100522 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
523 bvci_unblocked[i] := {};
524 }
525
Harald Weltefbae83f2020-11-15 23:25:55 +0100526 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100527 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100528 T.start;
529 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100530 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
531 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
532 [] as_count_unblocked4nse(0, bvci_unblocked);
533 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100534 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
535 repeat;
536 }
Harald Welte3c905152020-11-26 20:56:09 +0100537 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
538 repeat;
539 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100540 [] SGSN_MGMT.receive {
541 setverdict(fail, "Received unexpected message on SGSN_MGMT");
542 mtc.stop;
543 }
544
545 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
546 repeat;
547 }
548 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
549 repeat;
550 }
551 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
552 repeat;
553 }
554 [] PCU_MGMT.receive {
555 setverdict(fail, "Received unexpected message on PCU_MGMT");
556 mtc.stop;
557 }
558
559 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100560 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100561 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100562 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100563 }
564 }
565
Harald Welteb978ed62020-12-12 14:01:11 +0100566 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
567 /* iterate over list and check all BVCI */
568 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
569 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
570 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
571 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
572 mtc.stop;
573 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100574 }
575 }
Harald Welte425d3762020-12-09 14:33:18 +0100576
577 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
578 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200579}
580
581function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100582 var integer i;
583
Daniel Willmann491af2a2021-01-08 01:32:51 +0100584 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
585 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
586 * before the component is shutdown and disconnected. */
587 f_sleep(0.2);
588
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100589 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
590 f_destroy_gb(g_sgsn[i]);
591 }
592 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
593 f_destroy_gb(g_pcu[i]);
594 }
595
596 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200597}
598
599type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
600
601/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100602function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Harald Welte77218d02021-01-15 19:59:15 +0100603 float t_guard := 30.0, integer nri := mp_sgsn_nri[0][0])
Daniel Willmann423d8f42020-09-08 18:58:22 +0200604runs on test_CT return BSSGP_ConnHdlr {
605 var BSSGP_ConnHdlr vc_conn;
Harald Welte77218d02021-01-15 19:59:15 +0100606 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200607
608 var BSSGP_ConnHdlrPars pars := {
609 imei := f_gen_imei(imsi_suffix),
610 imsi := f_gen_imsi(imsi_suffix),
611 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100612 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200613 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100614 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200615 tlli_old := omit,
616 ra := omit,
Harald Welte77218d02021-01-15 19:59:15 +0100617 pcu := pcu,
618 sgsn := sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200619 t_guard := t_guard
620 };
621
622 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200623
624 vc_conn.start(f_handler_init(fn, id, pars));
625 return vc_conn;
626}
627
Harald Welte3dd21b32020-11-17 19:21:00 +0100628/* 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 +0100629private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
630runs on BSSGP_ConnHdlr {
631 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100632 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100633 /* unregister + disconnect from old BVC */
634 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100635 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100636 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
637 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
638 }
639 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100640 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100641 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
642 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
643 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
644 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100645 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100646}
647
648/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
649private 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 +0100650 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100651 /* unregister + disconnect from old BVC */
652 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100653 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100654 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
655 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
656 }
657 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100658 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100659 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
660 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
661 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
662 sgsn_ct[port_idx] := bvc_ct;
663}
664
Harald Welte425d3762020-12-09 14:33:18 +0100665private altstep as_gTguard(timer Tguard) {
666 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200667 setverdict(fail, "Tguard timeout");
668 mtc.stop;
669 }
670}
671
672/* first function called in every ConnHdlr */
673private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
674runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100675 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200676 /* do some common stuff like setting up g_pars */
677 g_pars := pars;
678
679 llc := f_llc_create(false);
680
Harald Welte3dd21b32020-11-17 19:21:00 +0100681 /* default connections on PCU side: First BVC of each NSE/PCU */
682 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100683 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100684 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100685
686 /* default connections on SGSN side: First BVC of each NSE/SGSN */
687 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
688 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100689 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200690
691 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100692 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200693
694 /* call the user-supplied test case function */
695 fn.apply(id);
696}
697
Harald Welte1e834f32020-11-15 20:02:59 +0100698private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
699runs on BSSGP_ConnHdlr {
700 PT.call(BSSGP_register_client:{imsi, tlli}) {
701 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
702 }
703}
704
705private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
706runs on BSSGP_ConnHdlr {
707 PT.call(BSSGP_unregister_client:{imsi}) {
708 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
709 }
710}
711
Harald Welte22ef5d92020-11-16 13:35:14 +0100712/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
713friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100714 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100715 var PDU_BSSGP rx;
716 timer T := 1.0;
717
Daniel Willmann4798fd72020-11-24 16:23:29 +0100718 if (use_sig) {
719 PCU_SIG[pcu_idx].send(tx);
720 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100721 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100722 }
723
Harald Welte22ef5d92020-11-16 13:35:14 +0100724 T.start;
725 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100726 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
727 setverdict(pass);
728 }
Harald Welte158becf2020-12-09 12:32:32 +0100729 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100730 setverdict(pass);
731 }
Harald Welte158becf2020-12-09 12:32:32 +0100732 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100733 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
734 mtc.stop;
735 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100736 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
737 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
738 mtc.stop;
739 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100740 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100741 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100742 mtc.stop;
743 }
744 }
745}
746
747/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
748friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100749 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100750 var PDU_BSSGP rx;
751 timer T := 1.0;
752
Daniel Willmann4798fd72020-11-24 16:23:29 +0100753 if (use_sig) {
754 SGSN_SIG[sgsn_idx].send(tx);
755 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100756 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100757 }
758
Harald Welte22ef5d92020-11-16 13:35:14 +0100759 T.start;
760 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100761 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
762 setverdict(pass);
763 }
Harald Welte158becf2020-12-09 12:32:32 +0100764 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100765 setverdict(pass);
766 }
Harald Welte158becf2020-12-09 12:32:32 +0100767 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100768 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
769 mtc.stop;
770 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100771 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
772 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
773 mtc.stop;
774 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100775 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100776 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100777 mtc.stop;
778 }
779 }
780}
Harald Welte1e834f32020-11-15 20:02:59 +0100781
Harald Welte3807ed12020-11-24 19:05:22 +0100782/***********************************************************************
783 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
784 ***********************************************************************/
785
786type component GlobalTest_CT extends test_CT {
787 port BSSGP_PT G_PCU[NUM_PCU];
788 port BSSGP_PT G_SGSN[NUM_SGSN];
789};
790
Harald Welte299aa482020-12-09 15:10:55 +0100791/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100792private function f_global_init() runs on GlobalTest_CT {
793 var integer i;
794 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
795 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
796 }
797 for (i := 0; i < lengthof(g_pcu); i := i+1) {
798 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
799 }
800}
801
Harald Welte299aa482020-12-09 15:10:55 +0100802/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
803private function f_global_init_ptp() runs on GlobalTest_CT {
804 var integer i;
805 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
806 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
807 }
808 for (i := 0; i < lengthof(g_pcu); i := i+1) {
809 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
810 }
811}
812
Harald Welte3807ed12020-11-24 19:05:22 +0100813/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
814friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
815 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
816 var PDU_BSSGP rx;
817 timer T := 1.0;
818
819 G_PCU[pcu_idx].send(tx);
820 T.start;
821 alt {
822 [] G_SGSN[sgsn_idx].receive(exp_rx) {
823 setverdict(pass);
824 }
825 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
826 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
827 mtc.stop;
828 }
829 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100830 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100831 mtc.stop;
832 }
833 }
834}
835
836/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
837friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
838 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
839 var PDU_BSSGP rx;
840 timer T := 1.0;
841
842 G_SGSN[sgsn_idx].send(tx);
843 T.start;
844 alt {
845 [] G_PCU[pcu_idx].receive(exp_rx) {
846 setverdict(pass);
847 }
848 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
849 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
850 mtc.stop;
851 }
852 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100853 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100854 mtc.stop;
855 }
856 }
857}
858
859
Daniel Willmann423d8f42020-09-08 18:58:22 +0200860/* TODO:
861 * Detach without Attach
862 * SM procedures without attach / RAU
863 * ATTACH / RAU
864 ** with / without authentication
865 ** with / without P-TMSI allocation
866 * re-transmissions of LLC frames
867 * PDP Context activation
868 ** with different GGSN config in SGSN VTY
869 ** with different PDP context type (v4/v6/v46)
870 ** timeout from GGSN
871 ** multiple / secondary PDP context
872 */
873
874private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
875 f_sleep(5.0);
876 setverdict(pass);
877}
878
879testcase TC_BVC_bringup() runs on test_CT {
880 var BSSGP_ConnHdlr vc_conn;
881 f_init();
882
883 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
884 vc_conn.done;
885
886 f_cleanup();
887}
888
889friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100890 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200891 timer T := 5.0;
892 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100893 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200894 T.start;
895 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100896 [] 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 +0200897 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
898 }
Harald Welte16357a92020-11-17 18:20:00 +0100899 [] 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 +0200900 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
901 mtc.stop;
902 }
903 [] T.timeout {
904 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
905 mtc.stop;
906 }
907 }
908 return '00'O;
909}
910
911friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100912 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200913 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100914 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 +0200915 T.start;
916 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100917 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
918 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200919 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
920 mtc.stop;
921 }
922 [] T.timeout {
923 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
924 mtc.stop;
925 }
926 }
927}
928
929
Harald Welte92686012020-11-15 21:45:49 +0100930/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
931private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100932 var integer ran_idx := 0;
933 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100934 var integer i;
935
Harald Welte0d5fceb2020-11-29 16:04:07 +0100936 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100937 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100938 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 +0100939 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100940 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 +0100941
Harald Welte0d5fceb2020-11-29 16:04:07 +0100942 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100943 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100944 }
945 setverdict(pass);
946}
947
948testcase TC_ul_unitdata() runs on test_CT
949{
950 var BSSGP_ConnHdlr vc_conn;
951 f_init();
952
953 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
954 vc_conn.done;
955 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
956
957 f_cleanup();
958}
959
Harald Welte78d8db92020-11-15 23:27:27 +0100960/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
961private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
962 var integer i;
963
Harald Welte0d5fceb2020-11-29 16:04:07 +0100964 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100965 var octetstring payload := f_rnd_octstring(i);
966 var template (value) PDU_BSSGP pdu_tx :=
967 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
968 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
969 var template (present) PDU_BSSGP pdu_rx :=
970 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
971
Harald Welte0d5fceb2020-11-29 16:04:07 +0100972 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100973 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100974 }
975 setverdict(pass);
976}
977
978testcase TC_dl_unitdata() runs on test_CT
979{
980 var BSSGP_ConnHdlr vc_conn;
981 f_init();
982
983 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
984 vc_conn.done;
985 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
986
987 f_cleanup();
988}
Harald Welte92686012020-11-15 21:45:49 +0100989
Harald Welte6dc2ac42020-11-16 09:16:17 +0100990private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
991 var integer i;
992
993 for (i := 0; i < 10; i := i+1) {
994 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
995 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
996 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
997
Harald Welte22ef5d92020-11-16 13:35:14 +0100998 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100999 }
1000 setverdict(pass);
1001}
1002testcase TC_ra_capability() runs on test_CT
1003{
1004 var BSSGP_ConnHdlr vc_conn;
1005 f_init();
1006
1007 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
1008 vc_conn.done;
1009 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1010
1011 f_cleanup();
1012}
1013
Daniel Willmannace3ece2020-11-16 19:53:26 +01001014private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1015 var integer i;
1016 var OCT1 tag;
1017 for (i := 0; i < 10; i := i+1) {
1018 tag := int2oct(23 + i, 1);
1019 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1020 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1021 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1022
1023 f_pcu2sgsn(pdu_tx, pdu_rx);
1024
1025 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1026 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1027 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1028
1029 f_sgsn2pcu(pdu_tx, pdu_rx);
1030 }
1031 setverdict(pass);
1032}
1033testcase TC_ra_capability_upd() runs on test_CT
1034{
1035 var BSSGP_ConnHdlr vc_conn;
1036 f_init();
1037
Daniel Willmann54833f22020-11-19 15:43:52 +01001038 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001039 vc_conn.done;
1040 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1041
1042 f_cleanup();
1043}
1044
Daniel Willmann165d6612020-11-19 14:27:29 +01001045private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1046 var integer i;
1047 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1048 for (i := 0; i < 10; i := i+1) {
1049 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1050 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1051 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1052
1053 f_pcu2sgsn(pdu_tx, pdu_rx);
1054 }
1055 setverdict(pass);
1056}
1057testcase TC_radio_status() runs on test_CT
1058{
1059 var BSSGP_ConnHdlr vc_conn;
1060 f_init();
1061
Daniel Willmann54833f22020-11-19 15:43:52 +01001062 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001063 vc_conn.done;
1064 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1065
1066 f_cleanup();
1067}
1068
Harald Welte3807ed12020-11-24 19:05:22 +01001069private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001070 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001071
Daniel Willmannfa67f492020-11-19 15:48:05 +01001072 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001073 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001074 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001075 var OCT4 tlli := f_gprs_tlli_random();
1076 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001077 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001078 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001079
Harald Welte3807ed12020-11-24 19:05:22 +01001080 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001081
Harald Welte3807ed12020-11-24 19:05:22 +01001082 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001083 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001084 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001085
Harald Welte3807ed12020-11-24 19:05:22 +01001086 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001087
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001088 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1089 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1090 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1091
1092 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1093
Daniel Willmannfa67f492020-11-19 15:48:05 +01001094 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001095 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001096 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001097 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001098
Harald Welte3807ed12020-11-24 19:05:22 +01001099 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001100 }
1101 setverdict(pass);
1102}
Harald Welte3807ed12020-11-24 19:05:22 +01001103testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001104{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001105 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001106 f_global_init();
1107 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001108 f_cleanup();
1109}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001110
Harald Welte3807ed12020-11-24 19:05:22 +01001111private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001112 var integer i;
1113
1114 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001115 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001116 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001117 var OCT4 tlli := f_gprs_tlli_random();
1118 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001119 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001120 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001121
Harald Welte3807ed12020-11-24 19:05:22 +01001122 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001123
Harald Welte3807ed12020-11-24 19:05:22 +01001124 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001125 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001126 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001127
Harald Welte3807ed12020-11-24 19:05:22 +01001128 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001129
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001130 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1131 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1132 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1133
1134 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1135
Daniel Willmann087a33d2020-11-19 15:58:43 +01001136 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001137 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001138 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001139 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001140
Harald Welte3807ed12020-11-24 19:05:22 +01001141 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001142 }
1143 setverdict(pass);
1144}
Harald Welte3807ed12020-11-24 19:05:22 +01001145testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001146{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001147 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001148 f_global_init();
1149 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001150 f_cleanup();
1151}
1152
Harald Weltef8ef0282020-11-18 12:16:59 +01001153/* test the load-sharing between multiple NS-VC on the BSS side */
1154private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1155 var integer i;
1156
1157 for (i := 0; i < 10; i := i+1) {
1158 var octetstring payload := f_rnd_octstring(i);
1159 var template (value) PDU_BSSGP pdu_tx :=
1160 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001161 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001162 }
1163 setverdict(pass);
1164}
1165testcase TC_load_sharing_dl() runs on test_CT_NS
1166{
1167 const integer num_ue := 10;
1168 var BSSGP_ConnHdlr vc_conn[num_ue];
1169 f_init();
1170
1171 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1172 * side so we get the raw NsUnitdataIndication and hence observe different
1173 * NSVCI */
1174 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1175 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1176
1177 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1178 * of the NS-VC is ALIVE/UNBLOCKED */
1179 f_sleep(3.0);
1180
1181 /* start parallel components generating DL-UNITDATA from the SGSN side */
1182 for (var integer i:= 0; i < num_ue; i := i+1) {
1183 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1184 }
1185
1186 /* now start counting all the messages that were queued before */
1187 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1188 var ro_integer rx_count := { 0, 0, 0, 0 };
1189 timer T := 2.0;
1190 T.start;
1191 alt {
1192 [] as_NsUdiCount(0, rx_count);
1193 [] as_NsUdiCount(1, rx_count);
1194 [] as_NsUdiCount(2, rx_count);
1195 [] as_NsUdiCount(3, rx_count);
1196 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1197 [] NS.receive(NsStatusIndication:?) { repeat; }
1198 [] NS.receive {
1199 setverdict(fail, "Rx unexpected NS");
1200 mtc.stop;
1201 }
1202 [] T.timeout {
1203 }
1204 }
1205 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1206 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1207 if (rx_count[i] == 0) {
1208 setverdict(fail, "Data not shared over all NSVC");
1209 }
1210 }
1211 setverdict(pass);
1212}
1213private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1214 var NsUnitdataIndication udi;
1215 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1216 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1217 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1218 repeat;
1219 }
1220}
1221type component test_CT_NS extends test_CT {
1222 port NS_PT NS;
1223};
1224
1225
Harald Welte0e188242020-11-22 21:46:48 +01001226/***********************************************************************
1227 * PAGING PS procedure
1228 ***********************************************************************/
1229
1230private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1231 boolean use_sig := false)
1232runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1233 var template (value) PDU_BSSGP pdu_tx;
1234 var template (present) PDU_BSSGP pdu_rx;
1235 /* we always specify '0' as BVCI in the templates below, as we override it with
1236 * 'p4' later anyway */
1237 pdu_rx := tr_BSSGP_PS_PAGING(0);
1238 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1239 if (ispresent(g_pars.p_tmsi)) {
1240 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1241 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1242 } else {
1243 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1244 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1245 }
1246 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1247 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1248 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001249 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001250 } else {
1251 SGSN_SIG[sgsn_idx].send(pdu_tx);
1252 }
1253 return pdu_rx;
1254}
1255
1256/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1257 * specified PCU index */
1258private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1259 boolean use_sig := false,integer pcu_idx := 0)
1260runs on BSSGP_ConnHdlr {
1261 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001262 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001263 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1264 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1265 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1266 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1267 timer T := 2.0;
1268 T.start;
1269 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001270 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001271 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001272 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001273 repeat;
1274 }
1275 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1276 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1277 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001278 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001279 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001280 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001281 repeat;
1282 }
Harald Welte158becf2020-12-09 12:32:32 +01001283 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001284 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1285 }
Harald Welte158becf2020-12-09 12:32:32 +01001286 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001287 setverdict(fail, "Paging received on unexpected BVC");
1288 }
1289 [] any from PCU_SIG.receive(exp_rx) {
1290 setverdict(fail, "Paging received on unexpected BVC");
1291 }
Harald Welte158becf2020-12-09 12:32:32 +01001292 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001293 setverdict(fail, "Different Paging than expected received PTP BVC");
1294 }
1295 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1296 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1297 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001298 [not test_done] T.timeout {
1299 setverdict(fail, "Timeout waiting for paging");
1300 }
1301 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001302 }
1303}
1304
Harald Welte7462a592020-11-23 22:07:07 +01001305/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1306private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1307 boolean use_sig := false)
1308runs on BSSGP_ConnHdlr {
1309 var template (present) PDU_BSSGP exp_rx;
1310 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1311 /* Expect paging to propagate to no BSS */
1312 timer T := 2.0;
1313 T.start;
1314 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001315 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001316 setverdict(fail, "Paging received on unexpected BVC");
1317 }
1318 [] any from PCU_SIG.receive(exp_rx) {
1319 setverdict(fail, "Paging received on unexpected BVC");
1320 }
Harald Welte158becf2020-12-09 12:32:32 +01001321 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001322 setverdict(fail, "Different Paging received on PTP BVC");
1323 }
1324 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1325 setverdict(fail, "Different Paging received on SIGNALING BVC");
1326 }
1327 [] T.timeout {
1328 setverdict(pass);
1329 }
1330 }
1331}
1332
Harald Welte0e188242020-11-22 21:46:48 +01001333private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1334{
1335 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1336 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1337 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1338}
1339testcase TC_paging_ps_ptp_bss() runs on test_CT {
1340 var BSSGP_ConnHdlr vc_conn;
1341 f_init();
1342
1343 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1344 vc_conn.done;
1345
1346 f_cleanup();
1347}
1348
1349/* PS-PAGING on PTP-BVC for Location Area */
1350private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1351{
1352 var template (present) PDU_BSSGP exp_rx;
1353 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1354 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1355 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1356}
1357testcase TC_paging_ps_ptp_lac() runs on test_CT {
1358 var BSSGP_ConnHdlr vc_conn;
1359 f_init();
1360
1361 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1362 vc_conn.done;
1363
1364 f_cleanup();
1365}
1366
Harald Welte7462a592020-11-23 22:07:07 +01001367/* PS-PAGING on PTP-BVC for unknown Location Area */
1368private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1369{
1370 var GSM_Types.LocationAreaIdentification unknown_la := {
1371 mcc_mnc := '567F99'H,
1372 lac := 33333
1373 };
1374 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1375 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1376}
1377testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1378 var BSSGP_ConnHdlr vc_conn;
1379 f_init();
1380
1381 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1382 vc_conn.done;
1383
1384 f_cleanup();
1385}
1386
Harald Welte0e188242020-11-22 21:46:48 +01001387/* PS-PAGING on PTP-BVC for Routeing Area */
1388private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1389{
1390 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1391 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1392 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1393}
1394testcase TC_paging_ps_ptp_rac() runs on test_CT {
1395 var BSSGP_ConnHdlr vc_conn;
1396 f_init();
1397
1398 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1399 vc_conn.done;
1400
1401 f_cleanup();
1402}
1403
Harald Welte7462a592020-11-23 22:07:07 +01001404/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1405private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1406{
1407 var RoutingAreaIdentification unknown_ra := {
1408 lai := {
1409 mcc_mnc := '567F99'H,
1410 lac := 33333
1411 },
1412 rac := 254
1413 };
1414 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1415 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1416}
1417testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1418 var BSSGP_ConnHdlr vc_conn;
1419 f_init();
1420
1421 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1422 vc_conn.done;
1423
1424 f_cleanup();
1425}
1426
Harald Welte0e188242020-11-22 21:46:48 +01001427/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1428private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1429{
1430 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1431 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1432}
1433testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1434 var BSSGP_ConnHdlr vc_conn;
1435 f_init();
1436
1437 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1438 vc_conn.done;
1439
1440 f_cleanup();
1441}
1442
Harald Welte7462a592020-11-23 22:07:07 +01001443/* PS-PAGING on PTP-BVC for unknown BVCI */
1444private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1445{
1446 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1447 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1448}
1449testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1450 var BSSGP_ConnHdlr vc_conn;
1451 f_init();
1452
1453 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1454 vc_conn.done;
1455
1456 f_cleanup();
1457}
1458
Harald Welte0e188242020-11-22 21:46:48 +01001459/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1460private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1461runs on BSSGP_ConnHdlr {
1462[] PCU_SIG[pcu_idx].receive(exp_rx) {
1463 if (ro_integer_contains(roi, pcu_idx)) {
1464 setverdict(fail, "Received multiple paging on same SIG BVC");
1465 }
1466 roi := roi & { pcu_idx };
1467 repeat;
1468 }
Harald Welte158becf2020-12-09 12:32:32 +01001469[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001470 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1471 }
1472[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1473 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1474 }
Harald Welte158becf2020-12-09 12:32:32 +01001475[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001476 setverdict(fail, "Different Paging than expected received PTP BVC");
1477 }
1478}
1479
1480type record of default ro_default;
1481
1482/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1483private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1484 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1485{
1486 var template (present) PDU_BSSGP exp_rx;
1487 exp_rx := f_send_paging_ps(p4, 0, true);
1488
1489 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1490 var ro_default defaults := {};
1491 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1492 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1493 defaults := defaults & { d };
1494 }
1495 f_sleep(2.0);
1496 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1497 deactivate(defaults[i]);
1498 }
1499 log("Paging received on PCU ", g_roi);
1500
1501 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1502 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1503 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1504 if (exp_on_i and not rx_on_i) {
1505 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1506 }
1507 if (not exp_on_i and rx_on_i) {
1508 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1509 }
1510 }
1511 setverdict(pass);
1512}
1513
1514/* PS-PAGING on SIG-BVC for BSS Area */
1515private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1516{
1517 /* we expect the paging to arrive on all three NSE */
1518 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1519}
1520testcase TC_paging_ps_sig_bss() runs on test_CT {
1521 var BSSGP_ConnHdlr vc_conn;
1522 f_init();
1523
1524 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1525 vc_conn.done;
1526
1527 f_cleanup();
1528}
1529
1530/* PS-PAGING on SIG-BVC for Location Area */
1531private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1532{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001533 /* The first LAC (13135) is shared by all three NSEs */
1534 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1535 /* Reset state */
1536 g_roi := {};
1537 /* Make LAC (13300) available on pcu index 2 */
1538 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1539 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001540}
1541testcase TC_paging_ps_sig_lac() runs on test_CT {
1542 var BSSGP_ConnHdlr vc_conn;
1543 f_init();
1544
1545 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1546 vc_conn.done;
1547
1548 f_cleanup();
1549}
1550
Harald Welte7462a592020-11-23 22:07:07 +01001551/* PS-PAGING on SIG-BVC for unknown Location Area */
1552private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1553{
1554 var GSM_Types.LocationAreaIdentification unknown_la := {
1555 mcc_mnc := '567F99'H,
1556 lac := 33333
1557 };
1558 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1559}
1560testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1561 var BSSGP_ConnHdlr vc_conn;
1562 f_init();
1563
1564 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1565 vc_conn.done;
1566
1567 f_cleanup();
1568}
1569
Harald Welte0e188242020-11-22 21:46:48 +01001570/* PS-PAGING on SIG-BVC for Routeing Area */
1571private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1572{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001573 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001574 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001575 g_roi := {};
1576 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1577 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1578 g_roi := {};
1579 /* PCU index 2 has two matching BVCs with the RA ID */
1580 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1581 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001582}
1583testcase TC_paging_ps_sig_rac() runs on test_CT {
1584 var BSSGP_ConnHdlr vc_conn;
1585 f_init();
1586
1587 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1588 vc_conn.done;
1589
1590 f_cleanup();
1591}
1592
Harald Welte7462a592020-11-23 22:07:07 +01001593/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1594private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1595{
1596 var RoutingAreaIdentification unknown_ra := {
1597 lai := {
1598 mcc_mnc := '567F99'H,
1599 lac := 33333
1600 },
1601 rac := 254
1602 };
1603 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1604}
1605testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1606 var BSSGP_ConnHdlr vc_conn;
1607 f_init();
1608
1609 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1610 vc_conn.done;
1611
1612 f_cleanup();
1613}
1614
Harald Welte0e188242020-11-22 21:46:48 +01001615/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1616private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1617{
1618 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1619}
1620testcase TC_paging_ps_sig_bvci() runs on test_CT {
1621 var BSSGP_ConnHdlr vc_conn;
1622 f_init();
1623
1624 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1625 vc_conn.done;
1626
1627 f_cleanup();
1628}
1629
Harald Welte7462a592020-11-23 22:07:07 +01001630/* PS-PAGING on SIG-BVC for unknown BVCI */
1631private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1632{
1633 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1634}
1635testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1636 var BSSGP_ConnHdlr vc_conn;
1637 f_init();
1638
1639 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1640 vc_conn.done;
1641
1642 f_cleanup();
1643}
1644
1645
Harald Welte0e188242020-11-22 21:46:48 +01001646
1647/***********************************************************************
1648 * PAGING CS procedure
1649 ***********************************************************************/
1650
1651private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1652 boolean use_sig := false)
1653runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1654 var template (value) PDU_BSSGP pdu_tx;
1655 var template (present) PDU_BSSGP pdu_rx;
1656 /* we always specify '0' as BVCI in the templates below, as we override it with
1657 * 'p4' later anyway */
1658 pdu_rx := tr_BSSGP_CS_PAGING(0);
1659 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1660 if (ispresent(g_pars.p_tmsi)) {
1661 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1662 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1663 } else {
1664 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1665 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1666 }
1667 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1668 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1669 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001670 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001671 } else {
1672 SGSN_SIG[sgsn_idx].send(pdu_tx);
1673 }
1674 return pdu_rx;
1675}
1676
1677/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1678 * specified PCU index */
1679private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1680 boolean use_sig := false,integer pcu_idx := 0)
1681runs on BSSGP_ConnHdlr {
1682 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001683 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001684 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1685 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1686 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1687 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1688 timer T := 2.0;
1689 T.start;
1690 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001691 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001692 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001693 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001694 repeat;
1695 }
1696 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1697 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1698 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001699 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001700 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001701 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001702 repeat;
1703 }
Harald Welte158becf2020-12-09 12:32:32 +01001704 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001705 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1706 }
Harald Welte158becf2020-12-09 12:32:32 +01001707 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001708 setverdict(fail, "Paging received on unexpected BVC");
1709 }
1710 [] any from PCU_SIG.receive(exp_rx) {
1711 setverdict(fail, "Paging received on unexpected BVC");
1712 }
Harald Welte158becf2020-12-09 12:32:32 +01001713 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001714 setverdict(fail, "Different Paging than expected received PTP BVC");
1715 }
1716 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1717 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1718 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001719 [not test_done] T.timeout {
1720 setverdict(fail, "Timeout while waiting for paging")
1721 }
1722 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001723 }
1724}
1725
Harald Welte7462a592020-11-23 22:07:07 +01001726/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1727private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1728 boolean use_sig := false)
1729runs on BSSGP_ConnHdlr {
1730 var template (present) PDU_BSSGP exp_rx;
1731 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1732 /* Expect paging to propagate to no BSS */
1733 timer T := 2.0;
1734 T.start;
1735 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001736 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001737 setverdict(fail, "Paging received on unexpected BVC");
1738 }
1739 [] any from PCU_SIG.receive(exp_rx) {
1740 setverdict(fail, "Paging received on unexpected BVC");
1741 }
Harald Welte158becf2020-12-09 12:32:32 +01001742 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001743 setverdict(fail, "Different Paging received on PTP BVC");
1744 }
1745 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1746 setverdict(fail, "Different Paging received on SIGNALING BVC");
1747 }
1748 [] T.timeout {
1749 setverdict(pass);
1750 }
1751 }
1752}
1753
Harald Welte0e188242020-11-22 21:46:48 +01001754private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1755{
1756 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1757 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1758 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1759}
1760testcase TC_paging_cs_ptp_bss() runs on test_CT {
1761 var BSSGP_ConnHdlr vc_conn;
1762 f_init();
1763
1764 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1765 vc_conn.done;
1766
1767 f_cleanup();
1768}
1769
1770/* CS-PAGING on PTP-BVC for Location Area */
1771private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1772{
1773 var template (present) PDU_BSSGP exp_rx;
1774 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1775 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1776 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1777}
1778testcase TC_paging_cs_ptp_lac() runs on test_CT {
1779 var BSSGP_ConnHdlr vc_conn;
1780 f_init();
1781
1782 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1783 vc_conn.done;
1784
1785 f_cleanup();
1786}
1787
Harald Welte7462a592020-11-23 22:07:07 +01001788/* CS-PAGING on PTP-BVC for unknown Location Area */
1789private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1790{
1791 var GSM_Types.LocationAreaIdentification unknown_la := {
1792 mcc_mnc := '567F99'H,
1793 lac := 33333
1794 };
1795 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1796 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1797}
1798testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1799 var BSSGP_ConnHdlr vc_conn;
1800 f_init();
1801
1802 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1803 vc_conn.done;
1804
1805 f_cleanup();
1806}
1807
Harald Welte0e188242020-11-22 21:46:48 +01001808/* CS-PAGING on PTP-BVC for Routeing Area */
1809private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1810{
1811 /* 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 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1814}
1815testcase TC_paging_cs_ptp_rac() runs on test_CT {
1816 var BSSGP_ConnHdlr vc_conn;
1817 f_init();
1818
1819 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1820 vc_conn.done;
1821
1822 f_cleanup();
1823}
1824
Harald Welte7462a592020-11-23 22:07:07 +01001825/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1826private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1827{
1828 var RoutingAreaIdentification unknown_ra := {
1829 lai := {
1830 mcc_mnc := '567F99'H,
1831 lac := 33333
1832 },
1833 rac := 254
1834 };
1835 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1836 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1837}
1838testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1839 var BSSGP_ConnHdlr vc_conn;
1840 f_init();
1841
1842 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1843 vc_conn.done;
1844
1845 f_cleanup();
1846}
1847
Harald Welte0e188242020-11-22 21:46:48 +01001848/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1849private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1850{
1851 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1852 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1853}
1854testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1855 var BSSGP_ConnHdlr vc_conn;
1856 f_init();
1857
1858 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1859 vc_conn.done;
1860
1861 f_cleanup();
1862}
1863
Harald Welte7462a592020-11-23 22:07:07 +01001864/* CS-PAGING on PTP-BVC for unknown BVCI */
1865private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1866{
1867 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1868 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1869}
1870testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1871 var BSSGP_ConnHdlr vc_conn;
1872 f_init();
1873
1874 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1875 vc_conn.done;
1876
1877 f_cleanup();
1878}
1879
Harald Welte0e188242020-11-22 21:46:48 +01001880/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1881private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1882 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1883{
1884 var template (present) PDU_BSSGP exp_rx;
1885 exp_rx := f_send_paging_cs(p4, 0, true);
1886
1887 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1888 var ro_default defaults := {};
1889 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1890 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1891 defaults := defaults & { d };
1892 }
1893 f_sleep(2.0);
1894 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1895 deactivate(defaults[i]);
1896 }
1897 log("Paging received on PCU ", g_roi);
1898
1899 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1900 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1901 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1902 if (exp_on_i and not rx_on_i) {
1903 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1904 }
1905 if (not exp_on_i and rx_on_i) {
1906 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1907 }
1908 }
1909 setverdict(pass);
1910}
1911
1912/* CS-PAGING on SIG-BVC for BSS Area */
1913private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1914{
1915 /* we expect the paging to arrive on all three NSE */
1916 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1917}
1918testcase TC_paging_cs_sig_bss() runs on test_CT {
1919 var BSSGP_ConnHdlr vc_conn;
1920 f_init();
1921
1922 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1923 vc_conn.done;
1924
1925 f_cleanup();
1926}
1927
1928/* CS-PAGING on SIG-BVC for Location Area */
1929private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1930{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001931 /* The first LAC (13135) is shared by all three NSEs */
1932 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1933 /* Reset state */
1934 g_roi := {};
1935 /* Make LAC (13300) available on pcu index 2 */
1936 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1937 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 +01001938}
1939testcase TC_paging_cs_sig_lac() runs on test_CT {
1940 var BSSGP_ConnHdlr vc_conn;
1941 f_init();
1942
1943 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1944 vc_conn.done;
1945
1946 f_cleanup();
1947}
1948
Harald Welte7462a592020-11-23 22:07:07 +01001949/* CS-PAGING on SIG-BVC for unknown Location Area */
1950private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1951{
1952 var GSM_Types.LocationAreaIdentification unknown_la := {
1953 mcc_mnc := '567F99'H,
1954 lac := 33333
1955 };
1956 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1957}
1958testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1959 var BSSGP_ConnHdlr vc_conn;
1960 f_init();
1961
1962 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1963 vc_conn.done;
1964
1965 f_cleanup();
1966}
1967
Harald Welte0e188242020-11-22 21:46:48 +01001968/* CS-PAGING on SIG-BVC for Routeing Area */
1969private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1970{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001971 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001972 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 +01001973 g_roi := {};
1974 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1975 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1976 g_roi := {};
1977 /* PCU index 2 has two matching BVCs with the RA ID */
1978 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1979 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 +01001980}
1981testcase TC_paging_cs_sig_rac() runs on test_CT {
1982 var BSSGP_ConnHdlr vc_conn;
1983 f_init();
1984
1985 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1986 vc_conn.done;
1987
1988 f_cleanup();
1989}
1990
Harald Welte7462a592020-11-23 22:07:07 +01001991/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1992private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1993{
1994 var RoutingAreaIdentification unknown_ra := {
1995 lai := {
1996 mcc_mnc := '567F99'H,
1997 lac := 33333
1998 },
1999 rac := 254
2000 };
2001 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2002}
2003testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
2004 var BSSGP_ConnHdlr vc_conn;
2005 f_init();
2006
2007 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
2008 vc_conn.done;
2009
2010 f_cleanup();
2011}
2012
Harald Welte0e188242020-11-22 21:46:48 +01002013/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2014private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2015{
2016 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2017}
2018testcase TC_paging_cs_sig_bvci() runs on test_CT {
2019 var BSSGP_ConnHdlr vc_conn;
2020 f_init();
2021
2022 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
2023 vc_conn.done;
2024
2025 f_cleanup();
2026}
2027
Harald Welte7462a592020-11-23 22:07:07 +01002028/* CS-PAGING on SIG-BVC for unknown BVCI */
2029private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2030{
2031 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2032}
2033testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
2034 var BSSGP_ConnHdlr vc_conn;
2035 f_init();
2036
2037 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
2038 vc_conn.done;
2039
2040 f_cleanup();
2041}
2042
Harald Welte4f91c3b2020-12-09 12:25:51 +01002043/***********************************************************************
2044 * FLUSH-LL procedure
2045 ***********************************************************************/
2046
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002047private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2048 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2049 var integer i;
2050 for (i := 0; i < 10; i := i+1) {
2051 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2053 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2054
2055 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2056
2057 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2058 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2059 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2060
2061 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2062 }
2063 setverdict(pass);
2064}
2065testcase TC_flush_ll() runs on test_CT
2066{
2067 var BSSGP_ConnHdlr vc_conn;
2068 f_init();
2069
2070 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2071 vc_conn.done;
2072 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2073
2074 f_cleanup();
2075}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002076
Harald Welte4f91c3b2020-12-09 12:25:51 +01002077/***********************************************************************
2078 * SGSN-INVOKE-TRACE procedure
2079 ***********************************************************************/
2080
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002081private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2082runs on GlobalTest_CT {
2083[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2084 if (ro_integer_contains(roi, pcu_idx)) {
2085 setverdict(fail, "Received multiple on same SIG BVC");
2086 }
2087 roi := roi & { pcu_idx };
2088 repeat;
2089 }
2090}
2091/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2092testcase TC_trace() runs on GlobalTest_CT
2093{
2094 var BSSGP_ConnHdlr vc_conn;
2095 f_init();
2096 f_global_init();
2097
2098 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2099 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2100
2101 var ro_default defaults := {};
2102 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2103 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2104 }
2105 G_SGSN[0].send(pdu_tx);
2106 f_sleep(2.0);
2107 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2108 deactivate(defaults[i]);
2109 }
2110
2111 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2112 if (not ro_integer_contains(g_roi, i)) {
2113 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2114 }
2115 }
2116 setverdict(pass);
2117
2118 f_cleanup();
2119}
2120
Harald Welte4f91c3b2020-12-09 12:25:51 +01002121/***********************************************************************
2122 * LLC-DISCARDED procedure
2123 ***********************************************************************/
2124
Harald Weltec0351d12020-11-27 22:49:02 +01002125private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2126 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2127
2128 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2129 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2130 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2131
2132 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2133
2134 setverdict(pass);
2135}
2136/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2137testcase TC_llc_discarded() runs on test_CT
2138{
2139 var BSSGP_ConnHdlr vc_conn;
2140 f_init();
2141
2142 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2143 vc_conn.done;
2144 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2145
2146 f_cleanup();
2147}
2148
Harald Welte4f91c3b2020-12-09 12:25:51 +01002149/***********************************************************************
2150 * OVERLOAD procedure
2151 ***********************************************************************/
2152
Harald Weltef20af412020-11-28 16:11:11 +01002153/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2154testcase TC_overload() runs on GlobalTest_CT
2155{
2156 f_init();
2157 f_global_init();
2158
2159 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2160 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2161
2162 var ro_default defaults := {};
2163 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2164 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2165 }
2166 G_SGSN[0].send(pdu_tx);
2167 f_sleep(2.0);
2168 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2169 deactivate(defaults[i]);
2170 }
2171
2172 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2173 if (not ro_integer_contains(g_roi, i)) {
2174 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2175 }
2176 }
2177 setverdict(pass);
2178
2179 f_cleanup();
2180}
2181
Harald Welte4f91c3b2020-12-09 12:25:51 +01002182/***********************************************************************
2183 * BVC-BLOCK / BVC-UNBLOCK procedure
2184 ***********************************************************************/
2185
Harald Welte239aa502020-11-24 23:14:20 +01002186private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2187{
2188 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2189 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2190 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2191
2192 SGSN_MGMT.clear;
2193 PCU_MGMT.clear;
2194
2195 /* block the PTP BVC from the PCU side */
2196 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2197 /* expect state on both PCU and SGSN side to change */
2198 interleave {
2199 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2200 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2201 }
2202 setverdict(pass);
2203}
2204testcase TC_bvc_block_ptp() runs on test_CT
2205{
2206 f_init();
2207 f_sleep(1.0);
2208 f_block_ptp_bvc_from_pcu(0, 0);
2209 f_cleanup();
2210}
2211
2212private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2213{
2214 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2215 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2216 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2217
2218 SGSN_MGMT.clear;
2219 PCU_MGMT.clear;
2220
2221 /* block the PTP BVC from the PCU side */
2222 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2223 /* expect state on both PCU and SGSN side to change */
2224 interleave {
2225 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2226 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2227 }
2228 setverdict(pass);
2229}
2230testcase TC_bvc_unblock_ptp() runs on test_CT
2231{
2232 f_init();
2233 f_sleep(1.0);
2234 f_block_ptp_bvc_from_pcu(0, 0);
2235 f_sleep(1.0);
2236 f_unblock_ptp_bvc_from_pcu(0, 0);
2237 f_cleanup();
2238}
2239
Harald Welte4f91c3b2020-12-09 12:25:51 +01002240/***********************************************************************
2241 * BVC-RESET procedure
2242 ***********************************************************************/
2243
Harald Welte60a8ec72020-11-25 17:12:53 +01002244private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2245[] pt.receive(BssgpStatusIndication:?) { repeat; }
2246}
2247private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2248 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2249 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2250 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2251 }
2252 }
2253 return null;
2254}
2255private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2256{
2257 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2258 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2259 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2260 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2261 var default d;
2262
2263 SGSN_MGMT.clear;
2264 PCU_MGMT.clear;
2265
2266 /* block the PTP BVC from the PCU side */
2267 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2268 /* expect state on both PCU and SGSN side to change */
2269 d := activate(as_ignore_status(SGSN_MGMT));
2270 interleave {
2271 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2272 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2273 }
2274 deactivate(d);
2275 setverdict(pass);
2276}
2277/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2278testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2279{
2280 f_init();
2281 f_sleep(3.0);
2282 f_reset_ptp_bvc_from_pcu(0, 0);
2283 f_cleanup();
2284}
2285
Harald Welte16786e92020-11-27 19:11:56 +01002286private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2287runs on test_CT {
2288 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2289 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2290 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002291 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002292 }
2293}
2294/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2295testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2296
2297 f_init();
2298 f_sleep(3.0);
2299
2300 /* Start BVC-RESET procedure for BVCI=0 */
2301 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2302
2303 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2304 var ro_default defaults := {};
2305 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2306 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2307 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2308 defaults := defaults & { d };
2309 }
2310
2311 timer T := 3.0;
2312 T.start;
2313 alt {
2314 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2315 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2316 }
2317 [] T.timeout;
2318 }
2319
2320 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2321 deactivate(defaults[i]);
2322 }
2323
2324 /* check if BVC-block was received on all expected BVC */
2325 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2326 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2327 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2328 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2329 }
2330 }
2331
2332 /* check if BVC-block was not received on any unexpected BVC is not required as
2333 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002334 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002335 f_cleanup();
2336}
2337
Harald Welte60a8ec72020-11-25 17:12:53 +01002338private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2339{
2340 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2341 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2342 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2343 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2344 var default d;
2345
2346 SGSN_MGMT.clear;
2347 PCU_MGMT.clear;
2348
2349 /* block the PTP BVC from the PCU side */
2350 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2351 /* expect state on both PCU and SGSN side to change */
2352 d := activate(as_ignore_status(PCU_MGMT));
2353 interleave {
2354 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2355 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2356 }
2357 deactivate(d);
2358 setverdict(pass);
2359}
2360/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2361testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2362{
2363 f_init();
2364 f_sleep(3.0);
2365 f_reset_ptp_bvc_from_sgsn(0, 0);
2366 f_cleanup();
2367}
2368
Daniel Willmannef7015f2021-01-08 00:43:56 +01002369private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2370 [] pt.receive {repeat; }
2371}
2372
Harald Welte16786e92020-11-27 19:11:56 +01002373private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2374runs on test_CT {
2375 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2376 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2377 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002378 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002379 }
2380}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002381
Harald Welte16786e92020-11-27 19:11:56 +01002382/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2383testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2384
2385 f_init();
2386 f_sleep(3.0);
2387
Daniel Willmannef7015f2021-01-08 00:43:56 +01002388 SGSN_MGMT.clear;
2389 PCU_MGMT.clear;
2390
Harald Welte16786e92020-11-27 19:11:56 +01002391 /* Start BVC-RESET procedure for BVCI=0 */
2392 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2393
Daniel Willmannef7015f2021-01-08 00:43:56 +01002394 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2395 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2396 * the port and a different message sits at the front we wait forever and fail the test.
2397 */
2398 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2399
Harald Welte16786e92020-11-27 19:11:56 +01002400 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002401 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2402 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2403 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2404 defaults := defaults & { d };
2405 }
2406
2407 f_sleep(3.0);
2408
2409 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2410 deactivate(defaults[i]);
2411 }
2412
2413 /* check if BVC-block was received on all expected BVC */
2414 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2415 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2416 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2417 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2418 }
2419 }
2420
2421 /* check if BVC-block was not received on any unexpected BVC is not required as
2422 * such a message would basically run into 'no matching clause' */
2423
2424 f_cleanup();
2425}
2426
Harald Welte299aa482020-12-09 15:10:55 +01002427/***********************************************************************
2428 * FLOW-CONTROL-BVC procedure
2429 ***********************************************************************/
2430
2431private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2432 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2433runs on GlobalTest_CT {
2434 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2435 roi := roi & { sgsn_idx };
2436 if (ispresent(tx_reply)) {
2437 G_SGSN[sgsn_idx].send(tx_reply);
2438 }
Harald Welte5fb01742021-01-15 21:07:52 +01002439 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002440 }
2441}
2442/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2443testcase TC_fc_bvc() runs on GlobalTest_CT
2444{
2445 f_init();
2446 f_global_init_ptp();
2447
2448 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2449 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2450 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2451 var template (omit) PDU_BSSGP ack_tx :=
2452 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2453
2454 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2455 G_PCU[0].send(pdu_tx);
2456
2457 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2458 var ro_default defaults := {};
2459 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2460 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2461 defaults := defaults & { d };
2462 }
2463
2464 f_sleep(3.0);
2465
2466 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2467 deactivate(defaults[i]);
2468 }
2469
2470 /* check if BVC-block was received on all expected BVC */
2471 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2472 if (not ro_integer_contains(g_roi, i)) {
2473 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2474 }
2475 }
2476
2477 /* Expect ACK on PCU side */
2478 G_PCU[0].receive(ack_tx);
2479
2480 setverdict(pass);
2481
2482 f_cleanup();
2483}
2484
Harald Weltecc3894b2020-12-09 16:50:12 +01002485/***********************************************************************
2486 * FLOW-CONTROL-MS procedure
2487 ***********************************************************************/
2488
2489private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2490 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2491
2492 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2493 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2494 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2495 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2496
2497 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2498 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2499
2500 setverdict(pass);
2501}
2502/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2503testcase TC_fc_ms() runs on test_CT
2504{
2505 var BSSGP_ConnHdlr vc_conn;
2506 f_init();
2507
2508 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2509 vc_conn.done;
2510 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2511
2512 f_cleanup();
2513}
2514
2515
Harald Welte299aa482020-12-09 15:10:55 +01002516
Daniel Willmann423d8f42020-09-08 18:58:22 +02002517control {
2518 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002519 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002520 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002521 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002522 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002523 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002524 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002525 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002526 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002527 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002528 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002529 execute( TC_bvc_block_ptp() );
2530 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002531 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002532 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002533 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002534 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002535 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002536 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2537 execute( TC_load_sharing_dl() );
2538 }
Harald Welte0e188242020-11-22 21:46:48 +01002539
2540 /* PAGING-PS over PTP BVC */
2541 execute( TC_paging_ps_ptp_bss() );
2542 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002543 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002544 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002545 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002546 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002547 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002548
2549 /* PAGING-PS over SIG BVC */
2550 execute( TC_paging_ps_sig_bss() );
2551 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002552 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002553 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002554 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002555 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002556 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002557
2558 /* PAGING-CS over PTP BVC */
2559 execute( TC_paging_cs_ptp_bss() );
2560 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002561 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002562 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002563 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002564 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002565 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002566
2567 /* PAGING-CS over SIG BVC */
2568 execute( TC_paging_cs_sig_bss() );
2569 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002570 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002571 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002572 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002573 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002574 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002575
2576
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002577 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002578 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002579 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002580}
2581
2582
2583}