blob: a0e6d1d6dafeefa2e46207485ee455b198acfce0 [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 Welte99ed5072021-01-15 20:38:58 +01001069private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1070 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001071runs on GlobalTest_CT
1072{
1073 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001074 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1075 nri_bitlen := mp_nri_bitlength);
1076 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001077 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1078 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1079 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1080 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1081
1082 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1083 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1084 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1085 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1086
1087 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1088 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1089 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1090 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1091
1092 /* These messages are simple passed through so just also test sending NACK */
1093 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1094 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1095 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1096 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1097}
1098
Harald Welte3807ed12020-11-24 19:05:22 +01001099private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001100 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001101
Daniel Willmannfa67f492020-11-19 15:48:05 +01001102 /* TODO: Generate RA ID for each ConnHdlr */
Daniel Willmannfa67f492020-11-19 15:48:05 +01001103 for (i := 0; i < 10; i := i+1) {
Harald Welte99ed5072021-01-15 20:38:58 +01001104 f_suspend_one(sgsn_idx := 0, nri_idx := 0, pcu_idx := 0, bvc_idx := 0, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001105 }
1106 setverdict(pass);
1107}
Harald Welte3807ed12020-11-24 19:05:22 +01001108testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001109{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001110 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001111 f_global_init();
1112 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001113 f_cleanup();
1114}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001115
Harald Welte99ed5072021-01-15 20:38:58 +01001116private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1117 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001118runs on GlobalTest_CT
1119{
1120 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001121 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1122 nri_bitlen := mp_nri_bitlength);
1123 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001124 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1125 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1126 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1127 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1128
1129 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1130 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1131 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1132 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1133
1134 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1135 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1136 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1137 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1138
1139 /* These messages are simple passed through so just also test sending NACK */
1140 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1141 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1142 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1143 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1144}
1145
Harald Welte3807ed12020-11-24 19:05:22 +01001146private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001147 var integer i;
1148
Daniel Willmann087a33d2020-11-19 15:58:43 +01001149 for (i := 0; i < 10; i := i+1) {
Harald Welte99ed5072021-01-15 20:38:58 +01001150 f_resume_one(sgsn_idx := 0, nri_idx := 0, pcu_idx := 0, bvc_idx := 0, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001151 }
1152 setverdict(pass);
1153}
Harald Welte3807ed12020-11-24 19:05:22 +01001154testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001155{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001156 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001157 f_global_init();
1158 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001159 f_cleanup();
1160}
1161
Harald Weltef8ef0282020-11-18 12:16:59 +01001162/* test the load-sharing between multiple NS-VC on the BSS side */
1163private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1164 var integer i;
1165
1166 for (i := 0; i < 10; i := i+1) {
1167 var octetstring payload := f_rnd_octstring(i);
1168 var template (value) PDU_BSSGP pdu_tx :=
1169 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001170 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001171 }
1172 setverdict(pass);
1173}
1174testcase TC_load_sharing_dl() runs on test_CT_NS
1175{
1176 const integer num_ue := 10;
1177 var BSSGP_ConnHdlr vc_conn[num_ue];
1178 f_init();
1179
1180 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1181 * side so we get the raw NsUnitdataIndication and hence observe different
1182 * NSVCI */
1183 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1184 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1185
1186 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1187 * of the NS-VC is ALIVE/UNBLOCKED */
1188 f_sleep(3.0);
1189
1190 /* start parallel components generating DL-UNITDATA from the SGSN side */
1191 for (var integer i:= 0; i < num_ue; i := i+1) {
1192 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1193 }
1194
1195 /* now start counting all the messages that were queued before */
1196 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1197 var ro_integer rx_count := { 0, 0, 0, 0 };
1198 timer T := 2.0;
1199 T.start;
1200 alt {
1201 [] as_NsUdiCount(0, rx_count);
1202 [] as_NsUdiCount(1, rx_count);
1203 [] as_NsUdiCount(2, rx_count);
1204 [] as_NsUdiCount(3, rx_count);
1205 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1206 [] NS.receive(NsStatusIndication:?) { repeat; }
1207 [] NS.receive {
1208 setverdict(fail, "Rx unexpected NS");
1209 mtc.stop;
1210 }
1211 [] T.timeout {
1212 }
1213 }
1214 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1215 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1216 if (rx_count[i] == 0) {
1217 setverdict(fail, "Data not shared over all NSVC");
1218 }
1219 }
1220 setverdict(pass);
1221}
1222private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1223 var NsUnitdataIndication udi;
1224 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1225 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1226 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1227 repeat;
1228 }
1229}
1230type component test_CT_NS extends test_CT {
1231 port NS_PT NS;
1232};
1233
1234
Harald Welte0e188242020-11-22 21:46:48 +01001235/***********************************************************************
1236 * PAGING PS procedure
1237 ***********************************************************************/
1238
1239private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1240 boolean use_sig := false)
1241runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1242 var template (value) PDU_BSSGP pdu_tx;
1243 var template (present) PDU_BSSGP pdu_rx;
1244 /* we always specify '0' as BVCI in the templates below, as we override it with
1245 * 'p4' later anyway */
1246 pdu_rx := tr_BSSGP_PS_PAGING(0);
1247 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1248 if (ispresent(g_pars.p_tmsi)) {
1249 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1250 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1251 } else {
1252 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1253 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1254 }
1255 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1256 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1257 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001258 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001259 } else {
1260 SGSN_SIG[sgsn_idx].send(pdu_tx);
1261 }
1262 return pdu_rx;
1263}
1264
1265/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1266 * specified PCU index */
1267private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1268 boolean use_sig := false,integer pcu_idx := 0)
1269runs on BSSGP_ConnHdlr {
1270 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001271 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001272 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1273 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1274 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1275 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1276 timer T := 2.0;
1277 T.start;
1278 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001279 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001280 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001281 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001282 repeat;
1283 }
1284 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1285 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1286 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001287 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001288 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001289 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001290 repeat;
1291 }
Harald Welte158becf2020-12-09 12:32:32 +01001292 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001293 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1294 }
Harald Welte158becf2020-12-09 12:32:32 +01001295 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001296 setverdict(fail, "Paging received on unexpected BVC");
1297 }
1298 [] any from PCU_SIG.receive(exp_rx) {
1299 setverdict(fail, "Paging received on unexpected BVC");
1300 }
Harald Welte158becf2020-12-09 12:32:32 +01001301 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001302 setverdict(fail, "Different Paging than expected received PTP BVC");
1303 }
1304 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1305 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1306 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001307 [not test_done] T.timeout {
1308 setverdict(fail, "Timeout waiting for paging");
1309 }
1310 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001311 }
1312}
1313
Harald Welte7462a592020-11-23 22:07:07 +01001314/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1315private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1316 boolean use_sig := false)
1317runs on BSSGP_ConnHdlr {
1318 var template (present) PDU_BSSGP exp_rx;
1319 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1320 /* Expect paging to propagate to no BSS */
1321 timer T := 2.0;
1322 T.start;
1323 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001324 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001325 setverdict(fail, "Paging received on unexpected BVC");
1326 }
1327 [] any from PCU_SIG.receive(exp_rx) {
1328 setverdict(fail, "Paging received on unexpected BVC");
1329 }
Harald Welte158becf2020-12-09 12:32:32 +01001330 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001331 setverdict(fail, "Different Paging received on PTP BVC");
1332 }
1333 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1334 setverdict(fail, "Different Paging received on SIGNALING BVC");
1335 }
1336 [] T.timeout {
1337 setverdict(pass);
1338 }
1339 }
1340}
1341
Harald Welte0e188242020-11-22 21:46:48 +01001342private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1343{
1344 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1345 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1346 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1347}
1348testcase TC_paging_ps_ptp_bss() runs on test_CT {
1349 var BSSGP_ConnHdlr vc_conn;
1350 f_init();
1351
1352 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1353 vc_conn.done;
1354
1355 f_cleanup();
1356}
1357
1358/* PS-PAGING on PTP-BVC for Location Area */
1359private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1360{
1361 var template (present) PDU_BSSGP exp_rx;
1362 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1363 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1364 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1365}
1366testcase TC_paging_ps_ptp_lac() runs on test_CT {
1367 var BSSGP_ConnHdlr vc_conn;
1368 f_init();
1369
1370 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1371 vc_conn.done;
1372
1373 f_cleanup();
1374}
1375
Harald Welte7462a592020-11-23 22:07:07 +01001376/* PS-PAGING on PTP-BVC for unknown Location Area */
1377private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1378{
1379 var GSM_Types.LocationAreaIdentification unknown_la := {
1380 mcc_mnc := '567F99'H,
1381 lac := 33333
1382 };
1383 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1384 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1385}
1386testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1387 var BSSGP_ConnHdlr vc_conn;
1388 f_init();
1389
1390 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1391 vc_conn.done;
1392
1393 f_cleanup();
1394}
1395
Harald Welte0e188242020-11-22 21:46:48 +01001396/* PS-PAGING on PTP-BVC for Routeing Area */
1397private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1398{
1399 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1400 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1401 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1402}
1403testcase TC_paging_ps_ptp_rac() runs on test_CT {
1404 var BSSGP_ConnHdlr vc_conn;
1405 f_init();
1406
1407 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1408 vc_conn.done;
1409
1410 f_cleanup();
1411}
1412
Harald Welte7462a592020-11-23 22:07:07 +01001413/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1414private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1415{
1416 var RoutingAreaIdentification unknown_ra := {
1417 lai := {
1418 mcc_mnc := '567F99'H,
1419 lac := 33333
1420 },
1421 rac := 254
1422 };
1423 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1424 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1425}
1426testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1427 var BSSGP_ConnHdlr vc_conn;
1428 f_init();
1429
1430 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1431 vc_conn.done;
1432
1433 f_cleanup();
1434}
1435
Harald Welte0e188242020-11-22 21:46:48 +01001436/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1437private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1438{
1439 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1440 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1441}
1442testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1443 var BSSGP_ConnHdlr vc_conn;
1444 f_init();
1445
1446 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1447 vc_conn.done;
1448
1449 f_cleanup();
1450}
1451
Harald Welte7462a592020-11-23 22:07:07 +01001452/* PS-PAGING on PTP-BVC for unknown BVCI */
1453private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1454{
1455 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1456 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1457}
1458testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1459 var BSSGP_ConnHdlr vc_conn;
1460 f_init();
1461
1462 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1463 vc_conn.done;
1464
1465 f_cleanup();
1466}
1467
Harald Welte0e188242020-11-22 21:46:48 +01001468/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1469private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1470runs on BSSGP_ConnHdlr {
1471[] PCU_SIG[pcu_idx].receive(exp_rx) {
1472 if (ro_integer_contains(roi, pcu_idx)) {
1473 setverdict(fail, "Received multiple paging on same SIG BVC");
1474 }
1475 roi := roi & { pcu_idx };
1476 repeat;
1477 }
Harald Welte158becf2020-12-09 12:32:32 +01001478[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001479 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1480 }
1481[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1482 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1483 }
Harald Welte158becf2020-12-09 12:32:32 +01001484[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001485 setverdict(fail, "Different Paging than expected received PTP BVC");
1486 }
1487}
1488
1489type record of default ro_default;
1490
1491/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1492private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1493 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1494{
1495 var template (present) PDU_BSSGP exp_rx;
1496 exp_rx := f_send_paging_ps(p4, 0, true);
1497
1498 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1499 var ro_default defaults := {};
1500 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1501 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1502 defaults := defaults & { d };
1503 }
1504 f_sleep(2.0);
1505 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1506 deactivate(defaults[i]);
1507 }
1508 log("Paging received on PCU ", g_roi);
1509
1510 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1511 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1512 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1513 if (exp_on_i and not rx_on_i) {
1514 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1515 }
1516 if (not exp_on_i and rx_on_i) {
1517 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1518 }
1519 }
1520 setverdict(pass);
1521}
1522
1523/* PS-PAGING on SIG-BVC for BSS Area */
1524private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1525{
1526 /* we expect the paging to arrive on all three NSE */
1527 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1528}
1529testcase TC_paging_ps_sig_bss() runs on test_CT {
1530 var BSSGP_ConnHdlr vc_conn;
1531 f_init();
1532
1533 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1534 vc_conn.done;
1535
1536 f_cleanup();
1537}
1538
1539/* PS-PAGING on SIG-BVC for Location Area */
1540private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1541{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001542 /* The first LAC (13135) is shared by all three NSEs */
1543 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1544 /* Reset state */
1545 g_roi := {};
1546 /* Make LAC (13300) available on pcu index 2 */
1547 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1548 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 +01001549}
1550testcase TC_paging_ps_sig_lac() runs on test_CT {
1551 var BSSGP_ConnHdlr vc_conn;
1552 f_init();
1553
1554 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1555 vc_conn.done;
1556
1557 f_cleanup();
1558}
1559
Harald Welte7462a592020-11-23 22:07:07 +01001560/* PS-PAGING on SIG-BVC for unknown Location Area */
1561private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1562{
1563 var GSM_Types.LocationAreaIdentification unknown_la := {
1564 mcc_mnc := '567F99'H,
1565 lac := 33333
1566 };
1567 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1568}
1569testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1570 var BSSGP_ConnHdlr vc_conn;
1571 f_init();
1572
1573 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1574 vc_conn.done;
1575
1576 f_cleanup();
1577}
1578
Harald Welte0e188242020-11-22 21:46:48 +01001579/* PS-PAGING on SIG-BVC for Routeing Area */
1580private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1581{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001582 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001583 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 +01001584 g_roi := {};
1585 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1586 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1587 g_roi := {};
1588 /* PCU index 2 has two matching BVCs with the RA ID */
1589 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1590 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 +01001591}
1592testcase TC_paging_ps_sig_rac() runs on test_CT {
1593 var BSSGP_ConnHdlr vc_conn;
1594 f_init();
1595
1596 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1597 vc_conn.done;
1598
1599 f_cleanup();
1600}
1601
Harald Welte7462a592020-11-23 22:07:07 +01001602/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1603private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1604{
1605 var RoutingAreaIdentification unknown_ra := {
1606 lai := {
1607 mcc_mnc := '567F99'H,
1608 lac := 33333
1609 },
1610 rac := 254
1611 };
1612 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1613}
1614testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1615 var BSSGP_ConnHdlr vc_conn;
1616 f_init();
1617
1618 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1619 vc_conn.done;
1620
1621 f_cleanup();
1622}
1623
Harald Welte0e188242020-11-22 21:46:48 +01001624/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1625private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1626{
1627 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1628}
1629testcase TC_paging_ps_sig_bvci() runs on test_CT {
1630 var BSSGP_ConnHdlr vc_conn;
1631 f_init();
1632
1633 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1634 vc_conn.done;
1635
1636 f_cleanup();
1637}
1638
Harald Welte7462a592020-11-23 22:07:07 +01001639/* PS-PAGING on SIG-BVC for unknown BVCI */
1640private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1641{
1642 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1643}
1644testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1645 var BSSGP_ConnHdlr vc_conn;
1646 f_init();
1647
1648 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1649 vc_conn.done;
1650
1651 f_cleanup();
1652}
1653
1654
Harald Welte0e188242020-11-22 21:46:48 +01001655
1656/***********************************************************************
1657 * PAGING CS procedure
1658 ***********************************************************************/
1659
1660private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1661 boolean use_sig := false)
1662runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1663 var template (value) PDU_BSSGP pdu_tx;
1664 var template (present) PDU_BSSGP pdu_rx;
1665 /* we always specify '0' as BVCI in the templates below, as we override it with
1666 * 'p4' later anyway */
1667 pdu_rx := tr_BSSGP_CS_PAGING(0);
1668 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1669 if (ispresent(g_pars.p_tmsi)) {
1670 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1671 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1672 } else {
1673 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1674 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1675 }
1676 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1677 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1678 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001679 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001680 } else {
1681 SGSN_SIG[sgsn_idx].send(pdu_tx);
1682 }
1683 return pdu_rx;
1684}
1685
1686/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1687 * specified PCU index */
1688private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1689 boolean use_sig := false,integer pcu_idx := 0)
1690runs on BSSGP_ConnHdlr {
1691 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001692 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001693 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1694 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1695 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1696 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1697 timer T := 2.0;
1698 T.start;
1699 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001700 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001701 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001702 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001703 repeat;
1704 }
1705 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1706 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1707 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001708 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001709 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001710 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001711 repeat;
1712 }
Harald Welte158becf2020-12-09 12:32:32 +01001713 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001714 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1715 }
Harald Welte158becf2020-12-09 12:32:32 +01001716 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001717 setverdict(fail, "Paging received on unexpected BVC");
1718 }
1719 [] any from PCU_SIG.receive(exp_rx) {
1720 setverdict(fail, "Paging received on unexpected BVC");
1721 }
Harald Welte158becf2020-12-09 12:32:32 +01001722 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001723 setverdict(fail, "Different Paging than expected received PTP BVC");
1724 }
1725 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1726 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1727 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001728 [not test_done] T.timeout {
1729 setverdict(fail, "Timeout while waiting for paging")
1730 }
1731 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001732 }
1733}
1734
Harald Welte7462a592020-11-23 22:07:07 +01001735/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1736private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1737 boolean use_sig := false)
1738runs on BSSGP_ConnHdlr {
1739 var template (present) PDU_BSSGP exp_rx;
1740 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1741 /* Expect paging to propagate to no BSS */
1742 timer T := 2.0;
1743 T.start;
1744 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001745 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001746 setverdict(fail, "Paging received on unexpected BVC");
1747 }
1748 [] any from PCU_SIG.receive(exp_rx) {
1749 setverdict(fail, "Paging received on unexpected BVC");
1750 }
Harald Welte158becf2020-12-09 12:32:32 +01001751 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001752 setverdict(fail, "Different Paging received on PTP BVC");
1753 }
1754 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1755 setverdict(fail, "Different Paging received on SIGNALING BVC");
1756 }
1757 [] T.timeout {
1758 setverdict(pass);
1759 }
1760 }
1761}
1762
Harald Welte0e188242020-11-22 21:46:48 +01001763private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1764{
1765 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1766 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1767 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1768}
1769testcase TC_paging_cs_ptp_bss() runs on test_CT {
1770 var BSSGP_ConnHdlr vc_conn;
1771 f_init();
1772
1773 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1774 vc_conn.done;
1775
1776 f_cleanup();
1777}
1778
1779/* CS-PAGING on PTP-BVC for Location Area */
1780private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1781{
1782 var template (present) PDU_BSSGP exp_rx;
1783 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1784 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1785 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1786}
1787testcase TC_paging_cs_ptp_lac() runs on test_CT {
1788 var BSSGP_ConnHdlr vc_conn;
1789 f_init();
1790
1791 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1792 vc_conn.done;
1793
1794 f_cleanup();
1795}
1796
Harald Welte7462a592020-11-23 22:07:07 +01001797/* CS-PAGING on PTP-BVC for unknown Location Area */
1798private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1799{
1800 var GSM_Types.LocationAreaIdentification unknown_la := {
1801 mcc_mnc := '567F99'H,
1802 lac := 33333
1803 };
1804 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1805 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1806}
1807testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1808 var BSSGP_ConnHdlr vc_conn;
1809 f_init();
1810
1811 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1812 vc_conn.done;
1813
1814 f_cleanup();
1815}
1816
Harald Welte0e188242020-11-22 21:46:48 +01001817/* CS-PAGING on PTP-BVC for Routeing Area */
1818private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1819{
1820 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1821 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1822 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1823}
1824testcase TC_paging_cs_ptp_rac() runs on test_CT {
1825 var BSSGP_ConnHdlr vc_conn;
1826 f_init();
1827
1828 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1829 vc_conn.done;
1830
1831 f_cleanup();
1832}
1833
Harald Welte7462a592020-11-23 22:07:07 +01001834/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1835private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1836{
1837 var RoutingAreaIdentification unknown_ra := {
1838 lai := {
1839 mcc_mnc := '567F99'H,
1840 lac := 33333
1841 },
1842 rac := 254
1843 };
1844 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1845 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1846}
1847testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1848 var BSSGP_ConnHdlr vc_conn;
1849 f_init();
1850
1851 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1852 vc_conn.done;
1853
1854 f_cleanup();
1855}
1856
Harald Welte0e188242020-11-22 21:46:48 +01001857/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1858private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1859{
1860 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1861 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1862}
1863testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1864 var BSSGP_ConnHdlr vc_conn;
1865 f_init();
1866
1867 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1868 vc_conn.done;
1869
1870 f_cleanup();
1871}
1872
Harald Welte7462a592020-11-23 22:07:07 +01001873/* CS-PAGING on PTP-BVC for unknown BVCI */
1874private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1875{
1876 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1877 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1878}
1879testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1880 var BSSGP_ConnHdlr vc_conn;
1881 f_init();
1882
1883 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1884 vc_conn.done;
1885
1886 f_cleanup();
1887}
1888
Harald Welte0e188242020-11-22 21:46:48 +01001889/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1890private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1891 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1892{
1893 var template (present) PDU_BSSGP exp_rx;
1894 exp_rx := f_send_paging_cs(p4, 0, true);
1895
1896 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1897 var ro_default defaults := {};
1898 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1899 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1900 defaults := defaults & { d };
1901 }
1902 f_sleep(2.0);
1903 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1904 deactivate(defaults[i]);
1905 }
1906 log("Paging received on PCU ", g_roi);
1907
1908 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1909 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1910 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1911 if (exp_on_i and not rx_on_i) {
1912 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1913 }
1914 if (not exp_on_i and rx_on_i) {
1915 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1916 }
1917 }
1918 setverdict(pass);
1919}
1920
1921/* CS-PAGING on SIG-BVC for BSS Area */
1922private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1923{
1924 /* we expect the paging to arrive on all three NSE */
1925 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1926}
1927testcase TC_paging_cs_sig_bss() runs on test_CT {
1928 var BSSGP_ConnHdlr vc_conn;
1929 f_init();
1930
1931 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1932 vc_conn.done;
1933
1934 f_cleanup();
1935}
1936
1937/* CS-PAGING on SIG-BVC for Location Area */
1938private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1939{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001940 /* The first LAC (13135) is shared by all three NSEs */
1941 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1942 /* Reset state */
1943 g_roi := {};
1944 /* Make LAC (13300) available on pcu index 2 */
1945 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1946 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 +01001947}
1948testcase TC_paging_cs_sig_lac() runs on test_CT {
1949 var BSSGP_ConnHdlr vc_conn;
1950 f_init();
1951
1952 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1953 vc_conn.done;
1954
1955 f_cleanup();
1956}
1957
Harald Welte7462a592020-11-23 22:07:07 +01001958/* CS-PAGING on SIG-BVC for unknown Location Area */
1959private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1960{
1961 var GSM_Types.LocationAreaIdentification unknown_la := {
1962 mcc_mnc := '567F99'H,
1963 lac := 33333
1964 };
1965 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1966}
1967testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1968 var BSSGP_ConnHdlr vc_conn;
1969 f_init();
1970
1971 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1972 vc_conn.done;
1973
1974 f_cleanup();
1975}
1976
Harald Welte0e188242020-11-22 21:46:48 +01001977/* CS-PAGING on SIG-BVC for Routeing Area */
1978private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1979{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001980 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001981 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 +01001982 g_roi := {};
1983 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1984 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1985 g_roi := {};
1986 /* PCU index 2 has two matching BVCs with the RA ID */
1987 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1988 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 +01001989}
1990testcase TC_paging_cs_sig_rac() runs on test_CT {
1991 var BSSGP_ConnHdlr vc_conn;
1992 f_init();
1993
1994 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1995 vc_conn.done;
1996
1997 f_cleanup();
1998}
1999
Harald Welte7462a592020-11-23 22:07:07 +01002000/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2001private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2002{
2003 var RoutingAreaIdentification unknown_ra := {
2004 lai := {
2005 mcc_mnc := '567F99'H,
2006 lac := 33333
2007 },
2008 rac := 254
2009 };
2010 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2011}
2012testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
2013 var BSSGP_ConnHdlr vc_conn;
2014 f_init();
2015
2016 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
2017 vc_conn.done;
2018
2019 f_cleanup();
2020}
2021
Harald Welte0e188242020-11-22 21:46:48 +01002022/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2023private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2024{
2025 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2026}
2027testcase TC_paging_cs_sig_bvci() runs on test_CT {
2028 var BSSGP_ConnHdlr vc_conn;
2029 f_init();
2030
2031 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
2032 vc_conn.done;
2033
2034 f_cleanup();
2035}
2036
Harald Welte7462a592020-11-23 22:07:07 +01002037/* CS-PAGING on SIG-BVC for unknown BVCI */
2038private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2039{
2040 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2041}
2042testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
2043 var BSSGP_ConnHdlr vc_conn;
2044 f_init();
2045
2046 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
2047 vc_conn.done;
2048
2049 f_cleanup();
2050}
2051
Harald Welte4f91c3b2020-12-09 12:25:51 +01002052/***********************************************************************
2053 * FLUSH-LL procedure
2054 ***********************************************************************/
2055
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002056private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2057 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2058 var integer i;
2059 for (i := 0; i < 10; i := i+1) {
2060 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2061 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2062 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2063
2064 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2065
2066 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2067 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2068 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2069
2070 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2071 }
2072 setverdict(pass);
2073}
2074testcase TC_flush_ll() runs on test_CT
2075{
2076 var BSSGP_ConnHdlr vc_conn;
2077 f_init();
2078
2079 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2080 vc_conn.done;
2081 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2082
2083 f_cleanup();
2084}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002085
Harald Welte4f91c3b2020-12-09 12:25:51 +01002086/***********************************************************************
2087 * SGSN-INVOKE-TRACE procedure
2088 ***********************************************************************/
2089
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002090private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2091runs on GlobalTest_CT {
2092[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2093 if (ro_integer_contains(roi, pcu_idx)) {
2094 setverdict(fail, "Received multiple on same SIG BVC");
2095 }
2096 roi := roi & { pcu_idx };
2097 repeat;
2098 }
2099}
2100/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2101testcase TC_trace() runs on GlobalTest_CT
2102{
2103 var BSSGP_ConnHdlr vc_conn;
2104 f_init();
2105 f_global_init();
2106
2107 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2108 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2109
2110 var ro_default defaults := {};
2111 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2112 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2113 }
2114 G_SGSN[0].send(pdu_tx);
2115 f_sleep(2.0);
2116 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2117 deactivate(defaults[i]);
2118 }
2119
2120 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2121 if (not ro_integer_contains(g_roi, i)) {
2122 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2123 }
2124 }
2125 setverdict(pass);
2126
2127 f_cleanup();
2128}
2129
Harald Welte4f91c3b2020-12-09 12:25:51 +01002130/***********************************************************************
2131 * LLC-DISCARDED procedure
2132 ***********************************************************************/
2133
Harald Weltec0351d12020-11-27 22:49:02 +01002134private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2135 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2136
2137 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2138 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2139 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2140
2141 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2142
2143 setverdict(pass);
2144}
2145/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2146testcase TC_llc_discarded() runs on test_CT
2147{
2148 var BSSGP_ConnHdlr vc_conn;
2149 f_init();
2150
2151 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2152 vc_conn.done;
2153 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2154
2155 f_cleanup();
2156}
2157
Harald Welte4f91c3b2020-12-09 12:25:51 +01002158/***********************************************************************
2159 * OVERLOAD procedure
2160 ***********************************************************************/
2161
Harald Weltef20af412020-11-28 16:11:11 +01002162/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2163testcase TC_overload() runs on GlobalTest_CT
2164{
2165 f_init();
2166 f_global_init();
2167
2168 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2169 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2170
2171 var ro_default defaults := {};
2172 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2173 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2174 }
2175 G_SGSN[0].send(pdu_tx);
2176 f_sleep(2.0);
2177 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2178 deactivate(defaults[i]);
2179 }
2180
2181 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2182 if (not ro_integer_contains(g_roi, i)) {
2183 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2184 }
2185 }
2186 setverdict(pass);
2187
2188 f_cleanup();
2189}
2190
Harald Welte4f91c3b2020-12-09 12:25:51 +01002191/***********************************************************************
2192 * BVC-BLOCK / BVC-UNBLOCK procedure
2193 ***********************************************************************/
2194
Harald Welte239aa502020-11-24 23:14:20 +01002195private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2196{
2197 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2198 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2199 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2200
2201 SGSN_MGMT.clear;
2202 PCU_MGMT.clear;
2203
2204 /* block the PTP BVC from the PCU side */
2205 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2206 /* expect state on both PCU and SGSN side to change */
2207 interleave {
2208 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2209 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2210 }
2211 setverdict(pass);
2212}
2213testcase TC_bvc_block_ptp() runs on test_CT
2214{
2215 f_init();
2216 f_sleep(1.0);
2217 f_block_ptp_bvc_from_pcu(0, 0);
2218 f_cleanup();
2219}
2220
2221private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2222{
2223 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2224 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2225 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2226
2227 SGSN_MGMT.clear;
2228 PCU_MGMT.clear;
2229
2230 /* block the PTP BVC from the PCU side */
2231 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2232 /* expect state on both PCU and SGSN side to change */
2233 interleave {
2234 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2235 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2236 }
2237 setverdict(pass);
2238}
2239testcase TC_bvc_unblock_ptp() runs on test_CT
2240{
2241 f_init();
2242 f_sleep(1.0);
2243 f_block_ptp_bvc_from_pcu(0, 0);
2244 f_sleep(1.0);
2245 f_unblock_ptp_bvc_from_pcu(0, 0);
2246 f_cleanup();
2247}
2248
Harald Welte4f91c3b2020-12-09 12:25:51 +01002249/***********************************************************************
2250 * BVC-RESET procedure
2251 ***********************************************************************/
2252
Harald Welte60a8ec72020-11-25 17:12:53 +01002253private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2254[] pt.receive(BssgpStatusIndication:?) { repeat; }
2255}
2256private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2257 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2258 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2259 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2260 }
2261 }
2262 return null;
2263}
2264private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2265{
2266 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2267 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2268 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2269 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2270 var default d;
2271
2272 SGSN_MGMT.clear;
2273 PCU_MGMT.clear;
2274
2275 /* block the PTP BVC from the PCU side */
2276 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2277 /* expect state on both PCU and SGSN side to change */
2278 d := activate(as_ignore_status(SGSN_MGMT));
2279 interleave {
2280 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2281 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2282 }
2283 deactivate(d);
2284 setverdict(pass);
2285}
2286/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2287testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2288{
2289 f_init();
2290 f_sleep(3.0);
2291 f_reset_ptp_bvc_from_pcu(0, 0);
2292 f_cleanup();
2293}
2294
Harald Welte16786e92020-11-27 19:11:56 +01002295private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2296runs on test_CT {
2297 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2298 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2299 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002300 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002301 }
2302}
2303/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2304testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2305
2306 f_init();
2307 f_sleep(3.0);
2308
2309 /* Start BVC-RESET procedure for BVCI=0 */
2310 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2311
2312 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2313 var ro_default defaults := {};
2314 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2315 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2316 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2317 defaults := defaults & { d };
2318 }
2319
2320 timer T := 3.0;
2321 T.start;
2322 alt {
2323 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2324 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2325 }
2326 [] T.timeout;
2327 }
2328
2329 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2330 deactivate(defaults[i]);
2331 }
2332
2333 /* check if BVC-block was received on all expected BVC */
2334 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2335 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2336 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2337 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2338 }
2339 }
2340
2341 /* check if BVC-block was not received on any unexpected BVC is not required as
2342 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002343 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002344 f_cleanup();
2345}
2346
Harald Welte60a8ec72020-11-25 17:12:53 +01002347private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2348{
2349 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2350 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2351 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2352 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2353 var default d;
2354
2355 SGSN_MGMT.clear;
2356 PCU_MGMT.clear;
2357
2358 /* block the PTP BVC from the PCU side */
2359 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2360 /* expect state on both PCU and SGSN side to change */
2361 d := activate(as_ignore_status(PCU_MGMT));
2362 interleave {
2363 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2364 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2365 }
2366 deactivate(d);
2367 setverdict(pass);
2368}
2369/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2370testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2371{
2372 f_init();
2373 f_sleep(3.0);
2374 f_reset_ptp_bvc_from_sgsn(0, 0);
2375 f_cleanup();
2376}
2377
Daniel Willmannef7015f2021-01-08 00:43:56 +01002378private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2379 [] pt.receive {repeat; }
2380}
2381
Harald Welte16786e92020-11-27 19:11:56 +01002382private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2383runs on test_CT {
2384 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2385 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2386 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002387 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002388 }
2389}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002390
Harald Welte16786e92020-11-27 19:11:56 +01002391/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2392testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2393
2394 f_init();
2395 f_sleep(3.0);
2396
Daniel Willmannef7015f2021-01-08 00:43:56 +01002397 SGSN_MGMT.clear;
2398 PCU_MGMT.clear;
2399
Harald Welte16786e92020-11-27 19:11:56 +01002400 /* Start BVC-RESET procedure for BVCI=0 */
2401 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2402
Daniel Willmannef7015f2021-01-08 00:43:56 +01002403 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2404 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2405 * the port and a different message sits at the front we wait forever and fail the test.
2406 */
2407 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2408
Harald Welte16786e92020-11-27 19:11:56 +01002409 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002410 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2411 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2412 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2413 defaults := defaults & { d };
2414 }
2415
2416 f_sleep(3.0);
2417
2418 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2419 deactivate(defaults[i]);
2420 }
2421
2422 /* check if BVC-block was received on all expected BVC */
2423 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2424 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2425 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2426 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2427 }
2428 }
2429
2430 /* check if BVC-block was not received on any unexpected BVC is not required as
2431 * such a message would basically run into 'no matching clause' */
2432
2433 f_cleanup();
2434}
2435
Harald Welte299aa482020-12-09 15:10:55 +01002436/***********************************************************************
2437 * FLOW-CONTROL-BVC procedure
2438 ***********************************************************************/
2439
2440private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2441 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2442runs on GlobalTest_CT {
2443 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2444 roi := roi & { sgsn_idx };
2445 if (ispresent(tx_reply)) {
2446 G_SGSN[sgsn_idx].send(tx_reply);
2447 }
Harald Welte5fb01742021-01-15 21:07:52 +01002448 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002449 }
2450}
2451/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2452testcase TC_fc_bvc() runs on GlobalTest_CT
2453{
2454 f_init();
2455 f_global_init_ptp();
2456
2457 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2458 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2459 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2460 var template (omit) PDU_BSSGP ack_tx :=
2461 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2462
2463 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2464 G_PCU[0].send(pdu_tx);
2465
2466 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2467 var ro_default defaults := {};
2468 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2469 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2470 defaults := defaults & { d };
2471 }
2472
2473 f_sleep(3.0);
2474
2475 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2476 deactivate(defaults[i]);
2477 }
2478
2479 /* check if BVC-block was received on all expected BVC */
2480 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2481 if (not ro_integer_contains(g_roi, i)) {
2482 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2483 }
2484 }
2485
2486 /* Expect ACK on PCU side */
2487 G_PCU[0].receive(ack_tx);
2488
2489 setverdict(pass);
2490
2491 f_cleanup();
2492}
2493
Harald Weltecc3894b2020-12-09 16:50:12 +01002494/***********************************************************************
2495 * FLOW-CONTROL-MS procedure
2496 ***********************************************************************/
2497
2498private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2499 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2500
2501 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2502 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2503 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2504 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2505
2506 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2507 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2508
2509 setverdict(pass);
2510}
2511/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2512testcase TC_fc_ms() runs on test_CT
2513{
2514 var BSSGP_ConnHdlr vc_conn;
2515 f_init();
2516
2517 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2518 vc_conn.done;
2519 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2520
2521 f_cleanup();
2522}
2523
2524
Harald Welte299aa482020-12-09 15:10:55 +01002525
Daniel Willmann423d8f42020-09-08 18:58:22 +02002526control {
2527 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002528 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002529 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002530 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002531 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002532 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002533 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002534 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002535 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002536 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002537 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002538 execute( TC_bvc_block_ptp() );
2539 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002540 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002541 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002542 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002543 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002544 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002545 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2546 execute( TC_load_sharing_dl() );
2547 }
Harald Welte0e188242020-11-22 21:46:48 +01002548
2549 /* PAGING-PS over PTP BVC */
2550 execute( TC_paging_ps_ptp_bss() );
2551 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002552 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002553 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002554 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002555 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002556 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002557
2558 /* PAGING-PS over SIG BVC */
2559 execute( TC_paging_ps_sig_bss() );
2560 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002561 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002562 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002563 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002564 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002565 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002566
2567 /* PAGING-CS over PTP BVC */
2568 execute( TC_paging_cs_ptp_bss() );
2569 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002570 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002571 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002572 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002573 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002574 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002575
2576 /* PAGING-CS over SIG BVC */
2577 execute( TC_paging_cs_sig_bss() );
2578 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002579 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002580 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002581 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002582 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002583 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002584
2585
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002586 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002587 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002588 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002589}
2590
2591
2592}