blob: 6f5b326ffef906670e38ab118b7fa1844f1b41c7 [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 Welte00963752021-01-15 20:33:11 +01001069private function f_suspend_one(integer sgsn_idx, integer pcu_idx, integer bvc_idx, integer suffix)
1070runs on GlobalTest_CT
1071{
1072 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
1073 var OCT4 tlli := f_gprs_tlli_random();
1074 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1075 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1076 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1077 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1078
1079 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1080 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1081 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1082 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1083
1084 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1085 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1086 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1087 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1088
1089 /* These messages are simple passed through so just also test sending NACK */
1090 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1091 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1092 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1093 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1094}
1095
Harald Welte3807ed12020-11-24 19:05:22 +01001096private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001097 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001098
Daniel Willmannfa67f492020-11-19 15:48:05 +01001099 /* TODO: Generate RA ID for each ConnHdlr */
Daniel Willmannfa67f492020-11-19 15:48:05 +01001100 for (i := 0; i < 10; i := i+1) {
Harald Welte00963752021-01-15 20:33:11 +01001101 f_suspend_one(0, 0, 0, i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001102 }
1103 setverdict(pass);
1104}
Harald Welte3807ed12020-11-24 19:05:22 +01001105testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001106{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001107 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001108 f_global_init();
1109 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001110 f_cleanup();
1111}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001112
Harald Welte00963752021-01-15 20:33:11 +01001113private function f_resume_one(integer sgsn_idx, integer pcu_idx, integer bvc_idx, integer suffix)
1114runs on GlobalTest_CT
1115{
1116 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
1117 var OCT4 tlli := f_gprs_tlli_random();
1118 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1119 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1120 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1121 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1122
1123 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1124 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1125 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1126 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1127
1128 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1129 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1130 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1131 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1132
1133 /* These messages are simple passed through so just also test sending NACK */
1134 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1135 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1136 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1137 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1138}
1139
Harald Welte3807ed12020-11-24 19:05:22 +01001140private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001141 var integer i;
1142
Daniel Willmann087a33d2020-11-19 15:58:43 +01001143 for (i := 0; i < 10; i := i+1) {
Harald Welte00963752021-01-15 20:33:11 +01001144 f_resume_one(0, 0, 0, i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001145 }
1146 setverdict(pass);
1147}
Harald Welte3807ed12020-11-24 19:05:22 +01001148testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001149{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001150 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001151 f_global_init();
1152 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001153 f_cleanup();
1154}
1155
Harald Weltef8ef0282020-11-18 12:16:59 +01001156/* test the load-sharing between multiple NS-VC on the BSS side */
1157private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1158 var integer i;
1159
1160 for (i := 0; i < 10; i := i+1) {
1161 var octetstring payload := f_rnd_octstring(i);
1162 var template (value) PDU_BSSGP pdu_tx :=
1163 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001164 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001165 }
1166 setverdict(pass);
1167}
1168testcase TC_load_sharing_dl() runs on test_CT_NS
1169{
1170 const integer num_ue := 10;
1171 var BSSGP_ConnHdlr vc_conn[num_ue];
1172 f_init();
1173
1174 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1175 * side so we get the raw NsUnitdataIndication and hence observe different
1176 * NSVCI */
1177 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1178 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1179
1180 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1181 * of the NS-VC is ALIVE/UNBLOCKED */
1182 f_sleep(3.0);
1183
1184 /* start parallel components generating DL-UNITDATA from the SGSN side */
1185 for (var integer i:= 0; i < num_ue; i := i+1) {
1186 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1187 }
1188
1189 /* now start counting all the messages that were queued before */
1190 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1191 var ro_integer rx_count := { 0, 0, 0, 0 };
1192 timer T := 2.0;
1193 T.start;
1194 alt {
1195 [] as_NsUdiCount(0, rx_count);
1196 [] as_NsUdiCount(1, rx_count);
1197 [] as_NsUdiCount(2, rx_count);
1198 [] as_NsUdiCount(3, rx_count);
1199 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1200 [] NS.receive(NsStatusIndication:?) { repeat; }
1201 [] NS.receive {
1202 setverdict(fail, "Rx unexpected NS");
1203 mtc.stop;
1204 }
1205 [] T.timeout {
1206 }
1207 }
1208 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1209 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1210 if (rx_count[i] == 0) {
1211 setverdict(fail, "Data not shared over all NSVC");
1212 }
1213 }
1214 setverdict(pass);
1215}
1216private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1217 var NsUnitdataIndication udi;
1218 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1219 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1220 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1221 repeat;
1222 }
1223}
1224type component test_CT_NS extends test_CT {
1225 port NS_PT NS;
1226};
1227
1228
Harald Welte0e188242020-11-22 21:46:48 +01001229/***********************************************************************
1230 * PAGING PS procedure
1231 ***********************************************************************/
1232
1233private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1234 boolean use_sig := false)
1235runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1236 var template (value) PDU_BSSGP pdu_tx;
1237 var template (present) PDU_BSSGP pdu_rx;
1238 /* we always specify '0' as BVCI in the templates below, as we override it with
1239 * 'p4' later anyway */
1240 pdu_rx := tr_BSSGP_PS_PAGING(0);
1241 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1242 if (ispresent(g_pars.p_tmsi)) {
1243 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1244 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1245 } else {
1246 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1247 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1248 }
1249 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1250 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1251 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001252 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001253 } else {
1254 SGSN_SIG[sgsn_idx].send(pdu_tx);
1255 }
1256 return pdu_rx;
1257}
1258
1259/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1260 * specified PCU index */
1261private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1262 boolean use_sig := false,integer pcu_idx := 0)
1263runs on BSSGP_ConnHdlr {
1264 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001265 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001266 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1267 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1268 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1269 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1270 timer T := 2.0;
1271 T.start;
1272 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001273 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001274 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001275 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001276 repeat;
1277 }
1278 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1279 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1280 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001281 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001282 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001283 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001284 repeat;
1285 }
Harald Welte158becf2020-12-09 12:32:32 +01001286 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001287 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1288 }
Harald Welte158becf2020-12-09 12:32:32 +01001289 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001290 setverdict(fail, "Paging received on unexpected BVC");
1291 }
1292 [] any from PCU_SIG.receive(exp_rx) {
1293 setverdict(fail, "Paging received on unexpected BVC");
1294 }
Harald Welte158becf2020-12-09 12:32:32 +01001295 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001296 setverdict(fail, "Different Paging than expected received PTP BVC");
1297 }
1298 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1299 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1300 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001301 [not test_done] T.timeout {
1302 setverdict(fail, "Timeout waiting for paging");
1303 }
1304 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001305 }
1306}
1307
Harald Welte7462a592020-11-23 22:07:07 +01001308/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1309private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1310 boolean use_sig := false)
1311runs on BSSGP_ConnHdlr {
1312 var template (present) PDU_BSSGP exp_rx;
1313 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1314 /* Expect paging to propagate to no BSS */
1315 timer T := 2.0;
1316 T.start;
1317 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001318 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001319 setverdict(fail, "Paging received on unexpected BVC");
1320 }
1321 [] any from PCU_SIG.receive(exp_rx) {
1322 setverdict(fail, "Paging received on unexpected BVC");
1323 }
Harald Welte158becf2020-12-09 12:32:32 +01001324 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001325 setverdict(fail, "Different Paging received on PTP BVC");
1326 }
1327 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1328 setverdict(fail, "Different Paging received on SIGNALING BVC");
1329 }
1330 [] T.timeout {
1331 setverdict(pass);
1332 }
1333 }
1334}
1335
Harald Welte0e188242020-11-22 21:46:48 +01001336private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1337{
1338 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1339 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1340 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1341}
1342testcase TC_paging_ps_ptp_bss() runs on test_CT {
1343 var BSSGP_ConnHdlr vc_conn;
1344 f_init();
1345
1346 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1347 vc_conn.done;
1348
1349 f_cleanup();
1350}
1351
1352/* PS-PAGING on PTP-BVC for Location Area */
1353private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1354{
1355 var template (present) PDU_BSSGP exp_rx;
1356 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1357 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1358 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1359}
1360testcase TC_paging_ps_ptp_lac() runs on test_CT {
1361 var BSSGP_ConnHdlr vc_conn;
1362 f_init();
1363
1364 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1365 vc_conn.done;
1366
1367 f_cleanup();
1368}
1369
Harald Welte7462a592020-11-23 22:07:07 +01001370/* PS-PAGING on PTP-BVC for unknown Location Area */
1371private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1372{
1373 var GSM_Types.LocationAreaIdentification unknown_la := {
1374 mcc_mnc := '567F99'H,
1375 lac := 33333
1376 };
1377 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1378 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1379}
1380testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1381 var BSSGP_ConnHdlr vc_conn;
1382 f_init();
1383
1384 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1385 vc_conn.done;
1386
1387 f_cleanup();
1388}
1389
Harald Welte0e188242020-11-22 21:46:48 +01001390/* PS-PAGING on PTP-BVC for Routeing Area */
1391private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1392{
1393 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1394 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1395 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1396}
1397testcase TC_paging_ps_ptp_rac() runs on test_CT {
1398 var BSSGP_ConnHdlr vc_conn;
1399 f_init();
1400
1401 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1402 vc_conn.done;
1403
1404 f_cleanup();
1405}
1406
Harald Welte7462a592020-11-23 22:07:07 +01001407/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1408private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1409{
1410 var RoutingAreaIdentification unknown_ra := {
1411 lai := {
1412 mcc_mnc := '567F99'H,
1413 lac := 33333
1414 },
1415 rac := 254
1416 };
1417 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1418 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1419}
1420testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1421 var BSSGP_ConnHdlr vc_conn;
1422 f_init();
1423
1424 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1425 vc_conn.done;
1426
1427 f_cleanup();
1428}
1429
Harald Welte0e188242020-11-22 21:46:48 +01001430/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1431private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1432{
1433 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1434 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1435}
1436testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1437 var BSSGP_ConnHdlr vc_conn;
1438 f_init();
1439
1440 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1441 vc_conn.done;
1442
1443 f_cleanup();
1444}
1445
Harald Welte7462a592020-11-23 22:07:07 +01001446/* PS-PAGING on PTP-BVC for unknown BVCI */
1447private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1448{
1449 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1450 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1451}
1452testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1453 var BSSGP_ConnHdlr vc_conn;
1454 f_init();
1455
1456 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1457 vc_conn.done;
1458
1459 f_cleanup();
1460}
1461
Harald Welte0e188242020-11-22 21:46:48 +01001462/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1463private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1464runs on BSSGP_ConnHdlr {
1465[] PCU_SIG[pcu_idx].receive(exp_rx) {
1466 if (ro_integer_contains(roi, pcu_idx)) {
1467 setverdict(fail, "Received multiple paging on same SIG BVC");
1468 }
1469 roi := roi & { pcu_idx };
1470 repeat;
1471 }
Harald Welte158becf2020-12-09 12:32:32 +01001472[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001473 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1474 }
1475[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1476 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1477 }
Harald Welte158becf2020-12-09 12:32:32 +01001478[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001479 setverdict(fail, "Different Paging than expected received PTP BVC");
1480 }
1481}
1482
1483type record of default ro_default;
1484
1485/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1486private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1487 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1488{
1489 var template (present) PDU_BSSGP exp_rx;
1490 exp_rx := f_send_paging_ps(p4, 0, true);
1491
1492 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1493 var ro_default defaults := {};
1494 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1495 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1496 defaults := defaults & { d };
1497 }
1498 f_sleep(2.0);
1499 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1500 deactivate(defaults[i]);
1501 }
1502 log("Paging received on PCU ", g_roi);
1503
1504 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1505 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1506 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1507 if (exp_on_i and not rx_on_i) {
1508 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1509 }
1510 if (not exp_on_i and rx_on_i) {
1511 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1512 }
1513 }
1514 setverdict(pass);
1515}
1516
1517/* PS-PAGING on SIG-BVC for BSS Area */
1518private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1519{
1520 /* we expect the paging to arrive on all three NSE */
1521 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1522}
1523testcase TC_paging_ps_sig_bss() runs on test_CT {
1524 var BSSGP_ConnHdlr vc_conn;
1525 f_init();
1526
1527 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1528 vc_conn.done;
1529
1530 f_cleanup();
1531}
1532
1533/* PS-PAGING on SIG-BVC for Location Area */
1534private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1535{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001536 /* The first LAC (13135) is shared by all three NSEs */
1537 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1538 /* Reset state */
1539 g_roi := {};
1540 /* Make LAC (13300) available on pcu index 2 */
1541 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1542 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 +01001543}
1544testcase TC_paging_ps_sig_lac() runs on test_CT {
1545 var BSSGP_ConnHdlr vc_conn;
1546 f_init();
1547
1548 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1549 vc_conn.done;
1550
1551 f_cleanup();
1552}
1553
Harald Welte7462a592020-11-23 22:07:07 +01001554/* PS-PAGING on SIG-BVC for unknown Location Area */
1555private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1556{
1557 var GSM_Types.LocationAreaIdentification unknown_la := {
1558 mcc_mnc := '567F99'H,
1559 lac := 33333
1560 };
1561 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1562}
1563testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1564 var BSSGP_ConnHdlr vc_conn;
1565 f_init();
1566
1567 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1568 vc_conn.done;
1569
1570 f_cleanup();
1571}
1572
Harald Welte0e188242020-11-22 21:46:48 +01001573/* PS-PAGING on SIG-BVC for Routeing Area */
1574private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1575{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001576 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001577 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 +01001578 g_roi := {};
1579 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1580 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1581 g_roi := {};
1582 /* PCU index 2 has two matching BVCs with the RA ID */
1583 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1584 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 +01001585}
1586testcase TC_paging_ps_sig_rac() runs on test_CT {
1587 var BSSGP_ConnHdlr vc_conn;
1588 f_init();
1589
1590 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1591 vc_conn.done;
1592
1593 f_cleanup();
1594}
1595
Harald Welte7462a592020-11-23 22:07:07 +01001596/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1597private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1598{
1599 var RoutingAreaIdentification unknown_ra := {
1600 lai := {
1601 mcc_mnc := '567F99'H,
1602 lac := 33333
1603 },
1604 rac := 254
1605 };
1606 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1607}
1608testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1609 var BSSGP_ConnHdlr vc_conn;
1610 f_init();
1611
1612 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1613 vc_conn.done;
1614
1615 f_cleanup();
1616}
1617
Harald Welte0e188242020-11-22 21:46:48 +01001618/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1619private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1620{
1621 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1622}
1623testcase TC_paging_ps_sig_bvci() runs on test_CT {
1624 var BSSGP_ConnHdlr vc_conn;
1625 f_init();
1626
1627 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1628 vc_conn.done;
1629
1630 f_cleanup();
1631}
1632
Harald Welte7462a592020-11-23 22:07:07 +01001633/* PS-PAGING on SIG-BVC for unknown BVCI */
1634private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1635{
1636 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1637}
1638testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1639 var BSSGP_ConnHdlr vc_conn;
1640 f_init();
1641
1642 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1643 vc_conn.done;
1644
1645 f_cleanup();
1646}
1647
1648
Harald Welte0e188242020-11-22 21:46:48 +01001649
1650/***********************************************************************
1651 * PAGING CS procedure
1652 ***********************************************************************/
1653
1654private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1655 boolean use_sig := false)
1656runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1657 var template (value) PDU_BSSGP pdu_tx;
1658 var template (present) PDU_BSSGP pdu_rx;
1659 /* we always specify '0' as BVCI in the templates below, as we override it with
1660 * 'p4' later anyway */
1661 pdu_rx := tr_BSSGP_CS_PAGING(0);
1662 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1663 if (ispresent(g_pars.p_tmsi)) {
1664 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1665 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1666 } else {
1667 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1668 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1669 }
1670 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1671 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1672 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001673 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001674 } else {
1675 SGSN_SIG[sgsn_idx].send(pdu_tx);
1676 }
1677 return pdu_rx;
1678}
1679
1680/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1681 * specified PCU index */
1682private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1683 boolean use_sig := false,integer pcu_idx := 0)
1684runs on BSSGP_ConnHdlr {
1685 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001686 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001687 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1688 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1689 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1690 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1691 timer T := 2.0;
1692 T.start;
1693 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001694 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001695 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001696 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001697 repeat;
1698 }
1699 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1700 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1701 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001702 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001703 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001704 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001705 repeat;
1706 }
Harald Welte158becf2020-12-09 12:32:32 +01001707 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001708 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1709 }
Harald Welte158becf2020-12-09 12:32:32 +01001710 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001711 setverdict(fail, "Paging received on unexpected BVC");
1712 }
1713 [] any from PCU_SIG.receive(exp_rx) {
1714 setverdict(fail, "Paging received on unexpected BVC");
1715 }
Harald Welte158becf2020-12-09 12:32:32 +01001716 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001717 setverdict(fail, "Different Paging than expected received PTP BVC");
1718 }
1719 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1720 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1721 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001722 [not test_done] T.timeout {
1723 setverdict(fail, "Timeout while waiting for paging")
1724 }
1725 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001726 }
1727}
1728
Harald Welte7462a592020-11-23 22:07:07 +01001729/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1730private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1731 boolean use_sig := false)
1732runs on BSSGP_ConnHdlr {
1733 var template (present) PDU_BSSGP exp_rx;
1734 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1735 /* Expect paging to propagate to no BSS */
1736 timer T := 2.0;
1737 T.start;
1738 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001739 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001740 setverdict(fail, "Paging received on unexpected BVC");
1741 }
1742 [] any from PCU_SIG.receive(exp_rx) {
1743 setverdict(fail, "Paging received on unexpected BVC");
1744 }
Harald Welte158becf2020-12-09 12:32:32 +01001745 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001746 setverdict(fail, "Different Paging received on PTP BVC");
1747 }
1748 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1749 setverdict(fail, "Different Paging received on SIGNALING BVC");
1750 }
1751 [] T.timeout {
1752 setverdict(pass);
1753 }
1754 }
1755}
1756
Harald Welte0e188242020-11-22 21:46:48 +01001757private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1758{
1759 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1760 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1761 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1762}
1763testcase TC_paging_cs_ptp_bss() runs on test_CT {
1764 var BSSGP_ConnHdlr vc_conn;
1765 f_init();
1766
1767 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1768 vc_conn.done;
1769
1770 f_cleanup();
1771}
1772
1773/* CS-PAGING on PTP-BVC for Location Area */
1774private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1775{
1776 var template (present) PDU_BSSGP exp_rx;
1777 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1778 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1779 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1780}
1781testcase TC_paging_cs_ptp_lac() runs on test_CT {
1782 var BSSGP_ConnHdlr vc_conn;
1783 f_init();
1784
1785 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1786 vc_conn.done;
1787
1788 f_cleanup();
1789}
1790
Harald Welte7462a592020-11-23 22:07:07 +01001791/* CS-PAGING on PTP-BVC for unknown Location Area */
1792private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1793{
1794 var GSM_Types.LocationAreaIdentification unknown_la := {
1795 mcc_mnc := '567F99'H,
1796 lac := 33333
1797 };
1798 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1799 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1800}
1801testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1802 var BSSGP_ConnHdlr vc_conn;
1803 f_init();
1804
1805 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1806 vc_conn.done;
1807
1808 f_cleanup();
1809}
1810
Harald Welte0e188242020-11-22 21:46:48 +01001811/* CS-PAGING on PTP-BVC for Routeing Area */
1812private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1813{
1814 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1815 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1816 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1817}
1818testcase TC_paging_cs_ptp_rac() runs on test_CT {
1819 var BSSGP_ConnHdlr vc_conn;
1820 f_init();
1821
1822 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1823 vc_conn.done;
1824
1825 f_cleanup();
1826}
1827
Harald Welte7462a592020-11-23 22:07:07 +01001828/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1829private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1830{
1831 var RoutingAreaIdentification unknown_ra := {
1832 lai := {
1833 mcc_mnc := '567F99'H,
1834 lac := 33333
1835 },
1836 rac := 254
1837 };
1838 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1839 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1840}
1841testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1842 var BSSGP_ConnHdlr vc_conn;
1843 f_init();
1844
1845 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1846 vc_conn.done;
1847
1848 f_cleanup();
1849}
1850
Harald Welte0e188242020-11-22 21:46:48 +01001851/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1852private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1853{
1854 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1855 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1856}
1857testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1858 var BSSGP_ConnHdlr vc_conn;
1859 f_init();
1860
1861 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1862 vc_conn.done;
1863
1864 f_cleanup();
1865}
1866
Harald Welte7462a592020-11-23 22:07:07 +01001867/* CS-PAGING on PTP-BVC for unknown BVCI */
1868private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1869{
1870 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1871 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1872}
1873testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1874 var BSSGP_ConnHdlr vc_conn;
1875 f_init();
1876
1877 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1878 vc_conn.done;
1879
1880 f_cleanup();
1881}
1882
Harald Welte0e188242020-11-22 21:46:48 +01001883/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1884private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1885 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1886{
1887 var template (present) PDU_BSSGP exp_rx;
1888 exp_rx := f_send_paging_cs(p4, 0, true);
1889
1890 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1891 var ro_default defaults := {};
1892 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1893 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1894 defaults := defaults & { d };
1895 }
1896 f_sleep(2.0);
1897 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1898 deactivate(defaults[i]);
1899 }
1900 log("Paging received on PCU ", g_roi);
1901
1902 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1903 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1904 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1905 if (exp_on_i and not rx_on_i) {
1906 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1907 }
1908 if (not exp_on_i and rx_on_i) {
1909 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1910 }
1911 }
1912 setverdict(pass);
1913}
1914
1915/* CS-PAGING on SIG-BVC for BSS Area */
1916private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1917{
1918 /* we expect the paging to arrive on all three NSE */
1919 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1920}
1921testcase TC_paging_cs_sig_bss() runs on test_CT {
1922 var BSSGP_ConnHdlr vc_conn;
1923 f_init();
1924
1925 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1926 vc_conn.done;
1927
1928 f_cleanup();
1929}
1930
1931/* CS-PAGING on SIG-BVC for Location Area */
1932private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1933{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001934 /* The first LAC (13135) is shared by all three NSEs */
1935 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1936 /* Reset state */
1937 g_roi := {};
1938 /* Make LAC (13300) available on pcu index 2 */
1939 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1940 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 +01001941}
1942testcase TC_paging_cs_sig_lac() runs on test_CT {
1943 var BSSGP_ConnHdlr vc_conn;
1944 f_init();
1945
1946 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1947 vc_conn.done;
1948
1949 f_cleanup();
1950}
1951
Harald Welte7462a592020-11-23 22:07:07 +01001952/* CS-PAGING on SIG-BVC for unknown Location Area */
1953private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1954{
1955 var GSM_Types.LocationAreaIdentification unknown_la := {
1956 mcc_mnc := '567F99'H,
1957 lac := 33333
1958 };
1959 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1960}
1961testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1962 var BSSGP_ConnHdlr vc_conn;
1963 f_init();
1964
1965 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1966 vc_conn.done;
1967
1968 f_cleanup();
1969}
1970
Harald Welte0e188242020-11-22 21:46:48 +01001971/* CS-PAGING on SIG-BVC for Routeing Area */
1972private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1973{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001974 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001975 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 +01001976 g_roi := {};
1977 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1978 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1979 g_roi := {};
1980 /* PCU index 2 has two matching BVCs with the RA ID */
1981 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1982 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 +01001983}
1984testcase TC_paging_cs_sig_rac() runs on test_CT {
1985 var BSSGP_ConnHdlr vc_conn;
1986 f_init();
1987
1988 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1989 vc_conn.done;
1990
1991 f_cleanup();
1992}
1993
Harald Welte7462a592020-11-23 22:07:07 +01001994/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1995private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1996{
1997 var RoutingAreaIdentification unknown_ra := {
1998 lai := {
1999 mcc_mnc := '567F99'H,
2000 lac := 33333
2001 },
2002 rac := 254
2003 };
2004 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2005}
2006testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
2007 var BSSGP_ConnHdlr vc_conn;
2008 f_init();
2009
2010 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
2011 vc_conn.done;
2012
2013 f_cleanup();
2014}
2015
Harald Welte0e188242020-11-22 21:46:48 +01002016/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2017private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2018{
2019 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2020}
2021testcase TC_paging_cs_sig_bvci() runs on test_CT {
2022 var BSSGP_ConnHdlr vc_conn;
2023 f_init();
2024
2025 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
2026 vc_conn.done;
2027
2028 f_cleanup();
2029}
2030
Harald Welte7462a592020-11-23 22:07:07 +01002031/* CS-PAGING on SIG-BVC for unknown BVCI */
2032private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2033{
2034 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2035}
2036testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
2037 var BSSGP_ConnHdlr vc_conn;
2038 f_init();
2039
2040 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
2041 vc_conn.done;
2042
2043 f_cleanup();
2044}
2045
Harald Welte4f91c3b2020-12-09 12:25:51 +01002046/***********************************************************************
2047 * FLUSH-LL procedure
2048 ***********************************************************************/
2049
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002050private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2051 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2052 var integer i;
2053 for (i := 0; i < 10; i := i+1) {
2054 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2055 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2056 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2057
2058 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2059
2060 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2061 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2062 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2063
2064 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2065 }
2066 setverdict(pass);
2067}
2068testcase TC_flush_ll() runs on test_CT
2069{
2070 var BSSGP_ConnHdlr vc_conn;
2071 f_init();
2072
2073 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2074 vc_conn.done;
2075 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2076
2077 f_cleanup();
2078}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002079
Harald Welte4f91c3b2020-12-09 12:25:51 +01002080/***********************************************************************
2081 * SGSN-INVOKE-TRACE procedure
2082 ***********************************************************************/
2083
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002084private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2085runs on GlobalTest_CT {
2086[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2087 if (ro_integer_contains(roi, pcu_idx)) {
2088 setverdict(fail, "Received multiple on same SIG BVC");
2089 }
2090 roi := roi & { pcu_idx };
2091 repeat;
2092 }
2093}
2094/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2095testcase TC_trace() runs on GlobalTest_CT
2096{
2097 var BSSGP_ConnHdlr vc_conn;
2098 f_init();
2099 f_global_init();
2100
2101 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2102 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2103
2104 var ro_default defaults := {};
2105 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2106 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2107 }
2108 G_SGSN[0].send(pdu_tx);
2109 f_sleep(2.0);
2110 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2111 deactivate(defaults[i]);
2112 }
2113
2114 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2115 if (not ro_integer_contains(g_roi, i)) {
2116 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2117 }
2118 }
2119 setverdict(pass);
2120
2121 f_cleanup();
2122}
2123
Harald Welte4f91c3b2020-12-09 12:25:51 +01002124/***********************************************************************
2125 * LLC-DISCARDED procedure
2126 ***********************************************************************/
2127
Harald Weltec0351d12020-11-27 22:49:02 +01002128private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2129 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2130
2131 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2132 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2133 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2134
2135 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2136
2137 setverdict(pass);
2138}
2139/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2140testcase TC_llc_discarded() runs on test_CT
2141{
2142 var BSSGP_ConnHdlr vc_conn;
2143 f_init();
2144
2145 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2146 vc_conn.done;
2147 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2148
2149 f_cleanup();
2150}
2151
Harald Welte4f91c3b2020-12-09 12:25:51 +01002152/***********************************************************************
2153 * OVERLOAD procedure
2154 ***********************************************************************/
2155
Harald Weltef20af412020-11-28 16:11:11 +01002156/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2157testcase TC_overload() runs on GlobalTest_CT
2158{
2159 f_init();
2160 f_global_init();
2161
2162 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2163 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2164
2165 var ro_default defaults := {};
2166 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2167 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2168 }
2169 G_SGSN[0].send(pdu_tx);
2170 f_sleep(2.0);
2171 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2172 deactivate(defaults[i]);
2173 }
2174
2175 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2176 if (not ro_integer_contains(g_roi, i)) {
2177 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2178 }
2179 }
2180 setverdict(pass);
2181
2182 f_cleanup();
2183}
2184
Harald Welte4f91c3b2020-12-09 12:25:51 +01002185/***********************************************************************
2186 * BVC-BLOCK / BVC-UNBLOCK procedure
2187 ***********************************************************************/
2188
Harald Welte239aa502020-11-24 23:14:20 +01002189private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2190{
2191 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2192 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2193 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2194
2195 SGSN_MGMT.clear;
2196 PCU_MGMT.clear;
2197
2198 /* block the PTP BVC from the PCU side */
2199 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2200 /* expect state on both PCU and SGSN side to change */
2201 interleave {
2202 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2203 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2204 }
2205 setverdict(pass);
2206}
2207testcase TC_bvc_block_ptp() runs on test_CT
2208{
2209 f_init();
2210 f_sleep(1.0);
2211 f_block_ptp_bvc_from_pcu(0, 0);
2212 f_cleanup();
2213}
2214
2215private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2216{
2217 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2218 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2219 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2220
2221 SGSN_MGMT.clear;
2222 PCU_MGMT.clear;
2223
2224 /* block the PTP BVC from the PCU side */
2225 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2226 /* expect state on both PCU and SGSN side to change */
2227 interleave {
2228 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2229 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2230 }
2231 setverdict(pass);
2232}
2233testcase TC_bvc_unblock_ptp() runs on test_CT
2234{
2235 f_init();
2236 f_sleep(1.0);
2237 f_block_ptp_bvc_from_pcu(0, 0);
2238 f_sleep(1.0);
2239 f_unblock_ptp_bvc_from_pcu(0, 0);
2240 f_cleanup();
2241}
2242
Harald Welte4f91c3b2020-12-09 12:25:51 +01002243/***********************************************************************
2244 * BVC-RESET procedure
2245 ***********************************************************************/
2246
Harald Welte60a8ec72020-11-25 17:12:53 +01002247private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2248[] pt.receive(BssgpStatusIndication:?) { repeat; }
2249}
2250private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2251 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2252 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2253 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2254 }
2255 }
2256 return null;
2257}
2258private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2259{
2260 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2261 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2262 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2263 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2264 var default d;
2265
2266 SGSN_MGMT.clear;
2267 PCU_MGMT.clear;
2268
2269 /* block the PTP BVC from the PCU side */
2270 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2271 /* expect state on both PCU and SGSN side to change */
2272 d := activate(as_ignore_status(SGSN_MGMT));
2273 interleave {
2274 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2275 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2276 }
2277 deactivate(d);
2278 setverdict(pass);
2279}
2280/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2281testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2282{
2283 f_init();
2284 f_sleep(3.0);
2285 f_reset_ptp_bvc_from_pcu(0, 0);
2286 f_cleanup();
2287}
2288
Harald Welte16786e92020-11-27 19:11:56 +01002289private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2290runs on test_CT {
2291 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2292 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2293 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002294 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002295 }
2296}
2297/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2298testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2299
2300 f_init();
2301 f_sleep(3.0);
2302
2303 /* Start BVC-RESET procedure for BVCI=0 */
2304 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2305
2306 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2307 var ro_default defaults := {};
2308 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2309 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2310 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2311 defaults := defaults & { d };
2312 }
2313
2314 timer T := 3.0;
2315 T.start;
2316 alt {
2317 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2318 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2319 }
2320 [] T.timeout;
2321 }
2322
2323 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2324 deactivate(defaults[i]);
2325 }
2326
2327 /* check if BVC-block was received on all expected BVC */
2328 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2329 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2330 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2331 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2332 }
2333 }
2334
2335 /* check if BVC-block was not received on any unexpected BVC is not required as
2336 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002337 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002338 f_cleanup();
2339}
2340
Harald Welte60a8ec72020-11-25 17:12:53 +01002341private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2342{
2343 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2344 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2345 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2346 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2347 var default d;
2348
2349 SGSN_MGMT.clear;
2350 PCU_MGMT.clear;
2351
2352 /* block the PTP BVC from the PCU side */
2353 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2354 /* expect state on both PCU and SGSN side to change */
2355 d := activate(as_ignore_status(PCU_MGMT));
2356 interleave {
2357 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2358 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2359 }
2360 deactivate(d);
2361 setverdict(pass);
2362}
2363/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2364testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2365{
2366 f_init();
2367 f_sleep(3.0);
2368 f_reset_ptp_bvc_from_sgsn(0, 0);
2369 f_cleanup();
2370}
2371
Daniel Willmannef7015f2021-01-08 00:43:56 +01002372private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2373 [] pt.receive {repeat; }
2374}
2375
Harald Welte16786e92020-11-27 19:11:56 +01002376private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2377runs on test_CT {
2378 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2379 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2380 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002381 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002382 }
2383}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002384
Harald Welte16786e92020-11-27 19:11:56 +01002385/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2386testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2387
2388 f_init();
2389 f_sleep(3.0);
2390
Daniel Willmannef7015f2021-01-08 00:43:56 +01002391 SGSN_MGMT.clear;
2392 PCU_MGMT.clear;
2393
Harald Welte16786e92020-11-27 19:11:56 +01002394 /* Start BVC-RESET procedure for BVCI=0 */
2395 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2396
Daniel Willmannef7015f2021-01-08 00:43:56 +01002397 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2398 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2399 * the port and a different message sits at the front we wait forever and fail the test.
2400 */
2401 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2402
Harald Welte16786e92020-11-27 19:11:56 +01002403 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002404 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2405 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2406 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2407 defaults := defaults & { d };
2408 }
2409
2410 f_sleep(3.0);
2411
2412 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2413 deactivate(defaults[i]);
2414 }
2415
2416 /* check if BVC-block was received on all expected BVC */
2417 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2418 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2419 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2420 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2421 }
2422 }
2423
2424 /* check if BVC-block was not received on any unexpected BVC is not required as
2425 * such a message would basically run into 'no matching clause' */
2426
2427 f_cleanup();
2428}
2429
Harald Welte299aa482020-12-09 15:10:55 +01002430/***********************************************************************
2431 * FLOW-CONTROL-BVC procedure
2432 ***********************************************************************/
2433
2434private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2435 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2436runs on GlobalTest_CT {
2437 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2438 roi := roi & { sgsn_idx };
2439 if (ispresent(tx_reply)) {
2440 G_SGSN[sgsn_idx].send(tx_reply);
2441 }
Harald Welte5fb01742021-01-15 21:07:52 +01002442 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002443 }
2444}
2445/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2446testcase TC_fc_bvc() runs on GlobalTest_CT
2447{
2448 f_init();
2449 f_global_init_ptp();
2450
2451 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2452 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2453 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2454 var template (omit) PDU_BSSGP ack_tx :=
2455 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2456
2457 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2458 G_PCU[0].send(pdu_tx);
2459
2460 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2461 var ro_default defaults := {};
2462 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2463 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2464 defaults := defaults & { d };
2465 }
2466
2467 f_sleep(3.0);
2468
2469 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2470 deactivate(defaults[i]);
2471 }
2472
2473 /* check if BVC-block was received on all expected BVC */
2474 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2475 if (not ro_integer_contains(g_roi, i)) {
2476 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2477 }
2478 }
2479
2480 /* Expect ACK on PCU side */
2481 G_PCU[0].receive(ack_tx);
2482
2483 setverdict(pass);
2484
2485 f_cleanup();
2486}
2487
Harald Weltecc3894b2020-12-09 16:50:12 +01002488/***********************************************************************
2489 * FLOW-CONTROL-MS procedure
2490 ***********************************************************************/
2491
2492private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2493 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2494
2495 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2496 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2497 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2498 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2499
2500 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2501 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2502
2503 setverdict(pass);
2504}
2505/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2506testcase TC_fc_ms() runs on test_CT
2507{
2508 var BSSGP_ConnHdlr vc_conn;
2509 f_init();
2510
2511 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2512 vc_conn.done;
2513 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2514
2515 f_cleanup();
2516}
2517
2518
Harald Welte299aa482020-12-09 15:10:55 +01002519
Daniel Willmann423d8f42020-09-08 18:58:22 +02002520control {
2521 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002522 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002523 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002524 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002525 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002526 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002527 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002528 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002529 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002530 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002531 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002532 execute( TC_bvc_block_ptp() );
2533 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002534 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002535 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002536 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002537 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002538 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002539 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2540 execute( TC_load_sharing_dl() );
2541 }
Harald Welte0e188242020-11-22 21:46:48 +01002542
2543 /* PAGING-PS over PTP BVC */
2544 execute( TC_paging_ps_ptp_bss() );
2545 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002546 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002547 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002548 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002549 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002550 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002551
2552 /* PAGING-PS over SIG BVC */
2553 execute( TC_paging_ps_sig_bss() );
2554 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002555 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002556 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002557 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002558 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002559 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002560
2561 /* PAGING-CS over PTP BVC */
2562 execute( TC_paging_cs_ptp_bss() );
2563 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002564 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002565 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002566 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002567 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002568 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002569
2570 /* PAGING-CS over SIG BVC */
2571 execute( TC_paging_cs_sig_bss() );
2572 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002573 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002574 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002575 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002576 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002577 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002578
2579
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002580 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002581 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002582 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002583}
2584
2585
2586}