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