blob: e1d2e59ebb7df6cc2282e390f8115d2c45d8b7f1 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
36
37import from LLC_Types all;
38import from LLC_Templates all;
39
40import from GSM_RR_Types all;
41
Harald Welte6d63f742020-11-15 19:44:04 +010042/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
43const BcdMccMnc c_mcc_mnc := '262F42'H;
44
Harald Welte0d5fceb2020-11-29 16:04:07 +010045/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
46const integer max_fr_info_size := 1600;
47
Daniel Willmann423d8f42020-09-08 18:58:22 +020048modulepar {
Harald Welte77218d02021-01-15 19:59:15 +010049 /* NRI bit-length. 0 for no pooling */
50 integer mp_nri_bitlength := 5;
51 roro_integer mp_sgsn_nri := {
52 { 3 }, /* list of NRIs of first SGSN */
53 { 4 } /* list of NRIs of second SGSN */
54 };
Harald Weltef6e59b02020-12-08 08:29:09 +010055 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010056 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010057 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020059 nsei := 101,
60 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010061 handle_sns := false,
62 nsvc := {
63 {
64 provider := {
65 ip := {
66 address_family := AF_INET,
67 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010068 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010069 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010070 remote_ip := "127.0.0.1",
71 data_weight := 1,
72 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010073 }
74 },
75 nsvci := 101
76 }
Harald Weltebe7afce2021-01-17 22:04:36 +010077
Harald Welte90f19742020-11-06 19:34:40 +010078 }
Harald Welteb978ed62020-12-12 14:01:11 +010079 }, {
80 nsei := 102,
81 role_sgsn := true,
82 handle_sns := false,
83 nsvc := {
84 {
85 provider := {
86 ip := {
87 address_family := AF_INET,
88 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +010089 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +010090 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010091 remote_ip := "127.0.0.1",
92 data_weight := 1,
93 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +010094 }
95 },
96 nsvci := 102
97 }
98 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020099 }
100 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100101 /* BSS NSEI start at 2000 + x
102 * NSVCI start from value of NSEI + 100
103 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100104 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200105 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100106 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200107 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100108 handle_sns := false,
109 nsvc := {
110 {
111 provider := {
112 ip := {
113 address_family := AF_INET,
114 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100115 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100116 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100117 remote_ip := "127.0.0.1",
118 data_weight := 1,
119 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100120 }
121 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100122 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100123 }
124 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200125 },
126 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200128 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100129 handle_sns := false,
130 nsvc := {
131 {
132 provider := {
133 ip := {
134 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100135 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100136 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100137 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100138 remote_ip := "127.0.0.1",
139 data_weight := 1,
140 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100141 }
142 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100143 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100144 }
145 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200146 },
147 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100148 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200149 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100150 handle_sns := false,
151 nsvc := {
152 {
153 provider := {
154 ip := {
155 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100156 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100157 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100158 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100159 remote_ip := "127.0.0.1",
160 data_weight := 1,
161 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100162 }
163 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100165 }
166 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200167 }
168 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100169 /* BVCI are NSEI*10 + x
170 * The first NSE only has one BVC, the second one 2 and so on
171 * The Cell ID is BVCI + 10000
172 * LAC/RAC are configured in such a way that:
173 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
174 * LAC 13300 is present twice in NSE(2003)
175 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
176 * RAI 13300-0 is present twice in NSE(2003)
177 */
Harald Welte6d63f742020-11-15 19:44:04 +0100178 BssgpConfigs mp_gbconfigs := {
179 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100180 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100181 sgsn_role := false,
182 bvc := {
183 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100184 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100185 cell_id := {
186 ra_id := {
187 lai := {
188 mcc_mnc := c_mcc_mnc,
189 lac := 13135
190 },
191 rac := 0
192 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100194 },
195 depth := BSSGP_DECODE_DEPTH_BSSGP,
196 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
197 }
198 }
199 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100200 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100201 sgsn_role := false,
202 bvc := {
203 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100204 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100205 cell_id := {
206 ra_id := {
207 lai := {
208 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100209 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100210 },
Harald Welte0e188242020-11-22 21:46:48 +0100211 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100212 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100213 cell_id := 30021
214 },
215 depth := BSSGP_DECODE_DEPTH_BSSGP,
216 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
217 },
218 {
219 bvci := 20022,
220 cell_id := {
221 ra_id := {
222 lai := {
223 mcc_mnc := c_mcc_mnc,
224 lac := 13135
225 },
226 rac := 2
227 },
228 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100229 },
230 depth := BSSGP_DECODE_DEPTH_BSSGP,
231 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
232 }
233 }
234 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100235 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100236 sgsn_role := false,
237 bvc := {
238 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100239 bvci := 20031,
240 cell_id := {
241 ra_id := {
242 lai := {
243 mcc_mnc := c_mcc_mnc,
244 lac := 13135
245 },
246 rac := 1
247 },
248 cell_id := 30031
249 },
250 depth := BSSGP_DECODE_DEPTH_BSSGP,
251 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
252 },
253 {
254 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100255 cell_id := {
256 ra_id := {
257 lai := {
258 mcc_mnc := c_mcc_mnc,
259 lac := 13300
260 },
261 rac := 0
262 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100263 cell_id := 30032
264 },
265 depth := BSSGP_DECODE_DEPTH_BSSGP,
266 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
267 },
268 {
269 bvci := 20033,
270 cell_id := {
271 ra_id := {
272 lai := {
273 mcc_mnc := c_mcc_mnc,
274 lac := 13300
275 },
276 rac := 0
277 },
278 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100279 },
280 depth := BSSGP_DECODE_DEPTH_BSSGP,
281 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
282 }
283 }
284 }
285 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200286};
287
Daniel Willmann423d8f42020-09-08 18:58:22 +0200288type record GbInstance {
289 NS_CT vc_NS,
290 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100291 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200292 BssgpConfig cfg
293};
Harald Welte67dc8c22020-11-17 18:32:29 +0100294type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200295
296const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100297type record of GbInstance GbInstances;
298type record of BssgpConfig BssgpConfigs;
299type record of NSConfiguration NSConfigurations;
300type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200301
Harald Welteb978ed62020-12-12 14:01:11 +0100302const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200303
304type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100305 var GbInstances g_pcu;
306 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200307
308 port BSSGP_CT_PROC_PT PROC;
309
Harald Weltefbae83f2020-11-15 23:25:55 +0100310 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
311 port BSSGP_BVC_MGMT_PT PCU_MGMT;
312
Daniel Willmann423d8f42020-09-08 18:58:22 +0200313 port TELNETasp_PT GBPVTY;
314
315 var boolean g_initialized := false;
316 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100317
318 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100319 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200320};
321
322type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100323 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100324 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200325 port BSSGP_PT PCU_SIG[NUM_PCU];
326 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100327 /* component reference to the component to which we're currently connected */
328 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100329 /* BSSGP BVC configuration of the component to which we're currently connected */
330 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100331
332 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100333 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200334 port BSSGP_PT SGSN_SIG[NUM_SGSN];
335 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100336 /* component reference to the component to which we're currently connected */
337 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200338
339 var BSSGP_ConnHdlrPars g_pars;
340 timer g_Tguard;
341 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100342
343 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200344}
345
346type record SGSN_ConnHdlrNetworkPars {
347 boolean expect_ptmsi,
348 boolean expect_auth,
349 boolean expect_ciph
350};
351
352type record BSSGP_ConnHdlrPars {
353 /* IMEI of the simulated ME */
354 hexstring imei,
355 /* IMSI of the simulated MS */
356 hexstring imsi,
357 /* MSISDN of the simulated MS (probably unused) */
358 hexstring msisdn,
359 /* P-TMSI allocated to the simulated MS */
360 OCT4 p_tmsi optional,
361 OCT3 p_tmsi_sig optional,
362 /* TLLI of the simulated MS */
363 OCT4 tlli,
364 OCT4 tlli_old optional,
365 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100366 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100367 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100368 /* The SGSN index to be used within the test */
369 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200370 float t_guard
371};
372
Harald Welte04358652021-01-17 13:48:13 +0100373private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
374{
375 var integer i;
376
377 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
378 if (gbi.cfg.bvc[i].bvci == bvci) {
379 return i;
380 }
381 }
382 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
383 return -1;
384}
385
Daniel Willmann423d8f42020-09-08 18:58:22 +0200386private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
387 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
388 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
389
390 var RoutingAreaIdentificationV ret := {
391 mccDigit1 := mcc_mnc[0],
392 mccDigit2 := mcc_mnc[1],
393 mccDigit3 := mcc_mnc[2],
394 mncDigit3 := mcc_mnc[3],
395 mncDigit1 := mcc_mnc[4],
396 mncDigit2 := mcc_mnc[5],
397 lac := int2oct(cell_id.ra_id.lai.lac, 16),
398 rac := int2oct(cell_id.ra_id.rac, 8)
399 }
400 return ret;
401};
402
Harald Welte95339432020-12-02 18:50:52 +0100403private function f_fix_create_cb(inout BssgpConfig cfg)
404{
405 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
406 if (not isbound(cfg.bvc[i].create_cb)) {
407 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
408 }
409 }
410}
411
Daniel Willmann423d8f42020-09-08 18:58:22 +0200412private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100413 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
414 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
415 gb.vc_NS := NS_CT.create(ns_id);
416 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200417 /* connect lower end of BSSGP emulation with NS upper port */
418 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
419
Harald Welteb419d0e2020-11-16 16:45:05 +0100420 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
421 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200422
423 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100424 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200425 connect(self:PROC, gb.vc_BSSGP:PROC);
426 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
427 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100428 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100429 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200430 }
Harald Welteb978ed62020-12-12 14:01:11 +0100431 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100432 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200433}
434
435private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100436 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
437 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
438 gb.vc_NS := NS_CT.create(ns_id);
439 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200440 /* connect lower end of BSSGP emulation with NS upper port */
441 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
442
Harald Welteb419d0e2020-11-16 16:45:05 +0100443 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
444 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200445
446 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100447 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200448 connect(self:PROC, gb.vc_BSSGP:PROC);
449 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
450 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100451 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100452 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200453 }
Harald Welteb978ed62020-12-12 14:01:11 +0100454 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100455 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200456}
457
458
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100459private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
460 gb.vc_NS.stop;
461 gb.vc_BSSGP.stop;
462
463 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
464 gb.vc_BSSGP_BVC[i].stop;
465 }
466}
467
Daniel Willmann423d8f42020-09-08 18:58:22 +0200468private function f_init_vty() runs on test_CT {
469 map(self:GBPVTY, system:GBPVTY);
470 f_vty_set_prompts(GBPVTY);
471 f_vty_transceive(GBPVTY, "enable");
472}
473
Harald Weltefbae83f2020-11-15 23:25:55 +0100474type record of integer ro_integer;
475
476private function ro_integer_contains(ro_integer r, integer x) return boolean {
477 for (var integer j := 0; j < lengthof(r); j := j+1) {
478 if (r[j] == x) {
479 return true;
480 }
481 }
482 return false;
483}
484
Harald Welteb978ed62020-12-12 14:01:11 +0100485private type record of ro_integer roro_integer;
486
487/* count the number of unblocked BVCI for each SGSN NSE */
488private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
489runs on test_CT {
490 var BssgpStatusIndication bsi;
491 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
492 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
493 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
494 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
495 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
496 repeat;
497 }
498 }
499 }
500}
501
Harald Welte425d3762020-12-09 14:33:18 +0100502function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100503 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100504 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200505 var integer i;
506
507 if (g_initialized == true) {
508 return;
509 }
510 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200511
Harald Welte425d3762020-12-09 14:33:18 +0100512 g_Tguard.start(t_guard);
513 activate(as_gTguard(g_Tguard));
514
Harald Welteb978ed62020-12-12 14:01:11 +0100515 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100516 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
517 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100518 /* make sure all have a proper crate_cb, which cannot be specified in config file */
519 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100520 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100521 bvcs := bvcs & g_pcu[i].cfg.bvc;
522 }
523
524 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
525 g_sgsn[i].cfg := {
526 nsei := mp_nsconfig_sgsn[i].nsei,
527 sgsn_role := true,
528 bvc := bvcs
529 }
Harald Welte6d63f742020-11-15 19:44:04 +0100530 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200531
532 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100533 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100534 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100535 }
536 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
537 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
538 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
539 }
540
541 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100542 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100543 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200544 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100545 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100546 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100547 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100548
Harald Welteb978ed62020-12-12 14:01:11 +0100549 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
550 bvci_unblocked[i] := {};
551 }
552
Harald Weltefbae83f2020-11-15 23:25:55 +0100553 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100554 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100555 T.start;
556 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100557 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
558 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
559 [] as_count_unblocked4nse(0, bvci_unblocked);
560 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100561 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
562 repeat;
563 }
Harald Welte3c905152020-11-26 20:56:09 +0100564 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
565 repeat;
566 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100567 [] SGSN_MGMT.receive {
568 setverdict(fail, "Received unexpected message on SGSN_MGMT");
569 mtc.stop;
570 }
571
572 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
573 repeat;
574 }
575 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
576 repeat;
577 }
578 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
579 repeat;
580 }
581 [] PCU_MGMT.receive {
582 setverdict(fail, "Received unexpected message on PCU_MGMT");
583 mtc.stop;
584 }
585
586 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100587 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100588 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100589 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100590 }
591 }
592
Harald Welteb978ed62020-12-12 14:01:11 +0100593 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
594 /* iterate over list and check all BVCI */
595 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
596 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
597 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
598 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
599 mtc.stop;
600 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100601 }
602 }
Harald Welte425d3762020-12-09 14:33:18 +0100603
604 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
605 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200606}
607
608function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100609 var integer i;
610
Daniel Willmann491af2a2021-01-08 01:32:51 +0100611 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
612 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
613 * before the component is shutdown and disconnected. */
614 f_sleep(0.2);
615
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100616 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
617 f_destroy_gb(g_sgsn[i]);
618 }
619 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
620 f_destroy_gb(g_pcu[i]);
621 }
622
623 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200624}
625
626type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
627
628/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100629function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
630 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200631runs on test_CT return BSSGP_ConnHdlr {
632 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100633 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100634 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200635
636 var BSSGP_ConnHdlrPars pars := {
637 imei := f_gen_imei(imsi_suffix),
638 imsi := f_gen_imsi(imsi_suffix),
639 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100640 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200641 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100642 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200643 tlli_old := omit,
644 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100645 pcu := g_pcu,
646 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100647 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200648 t_guard := t_guard
649 };
Harald Welte207166c2021-01-16 12:52:30 +0100650 if (not have_ptmsi) {
651 pars.p_tmsi := omit;
652 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200653
654 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200655
Harald Welte25a04b12021-01-17 11:09:49 +0100656 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
657 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200658 vc_conn.start(f_handler_init(fn, id, pars));
659 return vc_conn;
660}
661
Harald Welte207166c2021-01-16 12:52:30 +0100662function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
663 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100664runs on test_CT
665{
666 var integer sgsn_idx, nri_idx;
667 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
668 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
669 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
670 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100671 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
672 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100673 /* Idea: we could also run them in parallel ? */
674 vc_conn.done;
675 }
676 }
677}
678
Harald Welte3dd21b32020-11-17 19:21:00 +0100679/* 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 +0100680private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
681runs on BSSGP_ConnHdlr {
682 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100683 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100684 /* unregister + disconnect from old BVC */
685 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100686 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100687 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
688 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
689 }
690 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100691 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100692 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
693 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
694 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
695 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100696 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100697}
698
699/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
700private 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 +0100701 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100702 /* unregister + disconnect from old BVC */
703 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100704 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100705 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
706 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
707 }
708 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100709 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100710 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
711 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
712 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
713 sgsn_ct[port_idx] := bvc_ct;
714}
715
Harald Welte425d3762020-12-09 14:33:18 +0100716private altstep as_gTguard(timer Tguard) {
717 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200718 setverdict(fail, "Tguard timeout");
719 mtc.stop;
720 }
721}
722
723/* first function called in every ConnHdlr */
724private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
725runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100726 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200727 /* do some common stuff like setting up g_pars */
728 g_pars := pars;
729
730 llc := f_llc_create(false);
731
Harald Welte3dd21b32020-11-17 19:21:00 +0100732 /* default connections on PCU side: First BVC of each NSE/PCU */
733 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100734 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100735 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100736
737 /* default connections on SGSN side: First BVC of each NSE/SGSN */
738 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
739 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100740 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200741
742 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100743 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200744
745 /* call the user-supplied test case function */
746 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100747
748 for (i := 0; i < NUM_SGSN; i := i+1) {
749 if (SGSN_PROC[i].checkstate("Connected")) {
750 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
751 }
752 }
753
754 for (i := 0; i < NUM_PCU; i := i+1) {
755 if (PCU_PROC[i].checkstate("Connected")) {
756 f_client_unregister(g_pars.imsi, PCU_PROC[i])
757 }
758 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200759}
760
Harald Welte1e834f32020-11-15 20:02:59 +0100761private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
762runs on BSSGP_ConnHdlr {
763 PT.call(BSSGP_register_client:{imsi, tlli}) {
764 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
765 }
766}
767
768private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
769runs on BSSGP_ConnHdlr {
770 PT.call(BSSGP_unregister_client:{imsi}) {
771 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
772 }
773}
774
Harald Welte22ef5d92020-11-16 13:35:14 +0100775/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
776friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100777 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
778 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100779 var PDU_BSSGP rx;
780 timer T := 1.0;
781
Daniel Willmann4798fd72020-11-24 16:23:29 +0100782 if (use_sig) {
783 PCU_SIG[pcu_idx].send(tx);
784 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100785 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100786 }
787
Harald Welte22ef5d92020-11-16 13:35:14 +0100788 T.start;
789 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100790 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
791 setverdict(pass);
792 }
Harald Welte158becf2020-12-09 12:32:32 +0100793 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100794 setverdict(pass);
795 }
Harald Welte158becf2020-12-09 12:32:32 +0100796 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100797 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100798 mtc.stop;
799 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100800 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100801 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100802 mtc.stop;
803 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100804 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100805 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100806 mtc.stop;
807 }
808 }
809}
810
Harald Welte3148a962021-01-17 11:15:28 +0100811/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
812friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
813 integer pcu_idx := 0, boolean use_sig := false)
814runs on BSSGP_ConnHdlr return integer {
815 var integer rx_idx := -1;
816 var PDU_BSSGP rx;
817 timer T := 1.0;
818
819 if (use_sig) {
820 PCU_SIG[pcu_idx].send(tx);
821 } else {
822 PCU_PTP[pcu_idx].send(tx);
823 }
824
825 T.start;
826 alt {
827 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
828 setverdict(pass);
829 }
830 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
831 setverdict(pass);
832 }
833 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
834 setverdict(fail, "Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx);
835 mtc.stop;
836 }
837 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
838 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx);
839 mtc.stop;
840 }
841 [] T.timeout {
842 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
843 mtc.stop;
844 }
845 }
846 return rx_idx;
847}
848
Harald Welte22ef5d92020-11-16 13:35:14 +0100849/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
850friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100851 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
852 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100853 var PDU_BSSGP rx;
854 timer T := 1.0;
855
Daniel Willmann4798fd72020-11-24 16:23:29 +0100856 if (use_sig) {
857 SGSN_SIG[sgsn_idx].send(tx);
858 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100859 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100860 }
861
Harald Welte22ef5d92020-11-16 13:35:14 +0100862 T.start;
863 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100864 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
865 setverdict(pass);
866 }
Harald Welte158becf2020-12-09 12:32:32 +0100867 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100868 setverdict(pass);
869 }
Harald Welte158becf2020-12-09 12:32:32 +0100870 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100871 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
872 mtc.stop;
873 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100874 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
875 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
876 mtc.stop;
877 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100878 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100879 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100880 mtc.stop;
881 }
882 }
883}
Harald Welte1e834f32020-11-15 20:02:59 +0100884
Harald Welte3807ed12020-11-24 19:05:22 +0100885/***********************************************************************
886 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
887 ***********************************************************************/
888
889type component GlobalTest_CT extends test_CT {
890 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100891 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100892 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100893 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100894 port BSSGP_PT RIM_PCU[NUM_PCU];
895 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100896};
897
Harald Welte299aa482020-12-09 15:10:55 +0100898/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100899private function f_global_init() runs on GlobalTest_CT {
900 var integer i;
901 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
902 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100903 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100904 }
905 for (i := 0; i < lengthof(g_pcu); i := i+1) {
906 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100907 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100908 }
909}
910
Harald Welte299aa482020-12-09 15:10:55 +0100911/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
912private function f_global_init_ptp() runs on GlobalTest_CT {
913 var integer i;
914 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100915 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100916 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100917 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100918 }
919 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100920 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100921 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100922 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100923 }
924}
925
Harald Welte04358652021-01-17 13:48:13 +0100926/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
927private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
928{
929 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
930 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
931 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
932 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
933 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
934}
935
936/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
937private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
938{
939 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
940 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
941 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
942 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
943 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
944}
945
Harald Welte3807ed12020-11-24 19:05:22 +0100946/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
947friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
948 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100949 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100950 var PDU_BSSGP rx;
951 timer T := 1.0;
952
953 G_PCU[pcu_idx].send(tx);
954 T.start;
955 alt {
956 [] G_SGSN[sgsn_idx].receive(exp_rx) {
957 setverdict(pass);
958 }
Harald Welte04358652021-01-17 13:48:13 +0100959 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
960 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
961 }
Harald Welte3807ed12020-11-24 19:05:22 +0100962 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
963 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
964 mtc.stop;
965 }
966 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100967 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100968 mtc.stop;
969 }
970 }
971}
972
973/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
974friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
975 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100976 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100977 var PDU_BSSGP rx;
978 timer T := 1.0;
979
980 G_SGSN[sgsn_idx].send(tx);
981 T.start;
982 alt {
983 [] G_PCU[pcu_idx].receive(exp_rx) {
984 setverdict(pass);
985 }
Harald Welte04358652021-01-17 13:48:13 +0100986 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
987 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
988 }
Harald Welte3807ed12020-11-24 19:05:22 +0100989 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
990 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
991 mtc.stop;
992 }
993 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100994 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100995 mtc.stop;
996 }
997 }
998}
999
1000
Daniel Willmann423d8f42020-09-08 18:58:22 +02001001/* TODO:
1002 * Detach without Attach
1003 * SM procedures without attach / RAU
1004 * ATTACH / RAU
1005 ** with / without authentication
1006 ** with / without P-TMSI allocation
1007 * re-transmissions of LLC frames
1008 * PDP Context activation
1009 ** with different GGSN config in SGSN VTY
1010 ** with different PDP context type (v4/v6/v46)
1011 ** timeout from GGSN
1012 ** multiple / secondary PDP context
1013 */
1014
1015private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1016 f_sleep(5.0);
1017 setverdict(pass);
1018}
1019
1020testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001021 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001022 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001023 f_cleanup();
1024}
1025
1026friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001027 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001028 timer T := 5.0;
1029 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001030 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001031 T.start;
1032 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001033 [] 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 +02001034 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1035 }
Harald Welte16357a92020-11-17 18:20:00 +01001036 [] 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 +02001037 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
1038 mtc.stop;
1039 }
1040 [] T.timeout {
1041 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1042 mtc.stop;
1043 }
1044 }
1045 return '00'O;
1046}
1047
1048friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001049 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001050 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001051 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 +02001052 T.start;
1053 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001054 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1055 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001056 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
1057 mtc.stop;
1058 }
1059 [] T.timeout {
1060 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1061 mtc.stop;
1062 }
1063 }
1064}
1065
1066
Harald Welte92686012020-11-15 21:45:49 +01001067/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1068private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001069 var integer ran_idx := 0;
1070 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001071 var integer i;
1072
Harald Welte0d5fceb2020-11-29 16:04:07 +01001073 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001074 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001075 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 +01001076 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001077 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 +01001078
Harald Welte0d5fceb2020-11-29 16:04:07 +01001079 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001080 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001081 }
1082 setverdict(pass);
1083}
1084
1085testcase TC_ul_unitdata() runs on test_CT
1086{
Harald Welte92686012020-11-15 21:45:49 +01001087 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001088 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001089 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001090 f_cleanup();
1091}
1092
Harald Welte78d8db92020-11-15 23:27:27 +01001093/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1094private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1095 var integer i;
1096
Harald Welte0d5fceb2020-11-29 16:04:07 +01001097 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001098 var octetstring payload := f_rnd_octstring(i);
1099 var template (value) PDU_BSSGP pdu_tx :=
1100 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1101 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1102 var template (present) PDU_BSSGP pdu_rx :=
1103 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
1104
Harald Welte0d5fceb2020-11-29 16:04:07 +01001105 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001106 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001107 }
1108 setverdict(pass);
1109}
1110
1111testcase TC_dl_unitdata() runs on test_CT
1112{
Harald Welte78d8db92020-11-15 23:27:27 +01001113 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001114 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001115 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001116 f_cleanup();
1117}
Harald Welte92686012020-11-15 21:45:49 +01001118
Harald Welte6dc2ac42020-11-16 09:16:17 +01001119private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1120 var integer i;
1121
1122 for (i := 0; i < 10; i := i+1) {
1123 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1124 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1125 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1126
Harald Welte22ef5d92020-11-16 13:35:14 +01001127 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001128 }
1129 setverdict(pass);
1130}
1131testcase TC_ra_capability() runs on test_CT
1132{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001133 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001134 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001135 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001136 f_cleanup();
1137}
1138
Daniel Willmannace3ece2020-11-16 19:53:26 +01001139private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1140 var integer i;
1141 var OCT1 tag;
1142 for (i := 0; i < 10; i := i+1) {
1143 tag := int2oct(23 + i, 1);
1144 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1145 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1146 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1147
1148 f_pcu2sgsn(pdu_tx, pdu_rx);
1149
1150 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1151 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1152 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1153
1154 f_sgsn2pcu(pdu_tx, pdu_rx);
1155 }
1156 setverdict(pass);
1157}
1158testcase TC_ra_capability_upd() runs on test_CT
1159{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001160 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001161 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001162 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001163 f_cleanup();
1164}
1165
Daniel Willmann165d6612020-11-19 14:27:29 +01001166private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1167 var integer i;
1168 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1169 for (i := 0; i < 10; i := i+1) {
1170 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1171 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1172 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1173
1174 f_pcu2sgsn(pdu_tx, pdu_rx);
1175 }
1176 setverdict(pass);
1177}
1178testcase TC_radio_status() runs on test_CT
1179{
Daniel Willmann165d6612020-11-19 14:27:29 +01001180 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001181 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001182 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001183 f_cleanup();
1184}
1185
Harald Welte3148a962021-01-17 11:15:28 +01001186private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1187 var integer i;
1188 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1189 for (i := 0; i < 10; i := i+1) {
1190 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1191 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1192 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1193 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1194 f_pcu2sgsn(pdu_tx, pdu_rx);
1195 }
1196 setverdict(pass);
1197}
1198testcase TC_radio_status_tmsi() runs on test_CT
1199{
1200 f_init();
1201 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1202 f_cleanup();
1203}
1204
1205private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1206 var integer i;
1207 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1208 for (i := 0; i < 10; i := i+1) {
1209 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1210 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1211 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1212 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1213 }
1214 setverdict(pass);
1215}
1216testcase TC_radio_status_imsi() runs on test_CT
1217{
1218 f_init();
1219 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1220 f_cleanup();
1221}
1222
1223
1224
Harald Welte99ed5072021-01-15 20:38:58 +01001225private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1226 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001227runs on GlobalTest_CT
1228{
1229 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001230 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1231 nri_bitlen := mp_nri_bitlength);
1232 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001233 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1234 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1235 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1236 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1237
1238 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1239 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1240 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1241 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1242
1243 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1244 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1245 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1246 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1247
1248 /* These messages are simple passed through so just also test sending NACK */
1249 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1250 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1251 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1252 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1253}
1254
Harald Weltec5c33732021-01-15 21:04:35 +01001255private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1256runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001257 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001258
Daniel Willmannfa67f492020-11-19 15:48:05 +01001259 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001260 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001261 }
1262 setverdict(pass);
1263}
Harald Welte3807ed12020-11-24 19:05:22 +01001264testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001265{
Harald Weltec5c33732021-01-15 21:04:35 +01001266 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001267 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001268 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001269 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1270 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1271 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1272 }
1273 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001274 f_cleanup();
1275}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001276
Harald Welte99ed5072021-01-15 20:38:58 +01001277private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1278 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001279runs on GlobalTest_CT
1280{
1281 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001282 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1283 nri_bitlen := mp_nri_bitlength);
1284 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001285 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1286 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1287 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1288 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1289
1290 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1291 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1292 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1293 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1294
1295 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1296 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1297 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1298 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1299
1300 /* These messages are simple passed through so just also test sending NACK */
1301 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1302 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1303 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1304 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1305}
1306
Harald Weltec5c33732021-01-15 21:04:35 +01001307private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1308runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001309 var integer i;
1310
Daniel Willmann087a33d2020-11-19 15:58:43 +01001311 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001312 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001313 }
1314 setverdict(pass);
1315}
Harald Welte3807ed12020-11-24 19:05:22 +01001316testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001317{
Harald Weltec5c33732021-01-15 21:04:35 +01001318 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001319 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001320 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001321 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1322 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1323 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1324 }
1325 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001326 f_cleanup();
1327}
1328
Harald Weltef8ef0282020-11-18 12:16:59 +01001329/* test the load-sharing between multiple NS-VC on the BSS side */
1330private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1331 var integer i;
1332
1333 for (i := 0; i < 10; i := i+1) {
1334 var octetstring payload := f_rnd_octstring(i);
1335 var template (value) PDU_BSSGP pdu_tx :=
1336 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001337 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001338 }
1339 setverdict(pass);
1340}
Harald Welte09a1ce42021-01-16 11:18:38 +01001341
1342private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001343{
1344 const integer num_ue := 10;
1345 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001346 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1347 * side so we get the raw NsUnitdataIndication and hence observe different
1348 * NSVCI */
1349 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1350 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1351
1352 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1353 * of the NS-VC is ALIVE/UNBLOCKED */
1354 f_sleep(3.0);
1355
1356 /* start parallel components generating DL-UNITDATA from the SGSN side */
1357 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001358 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001359 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001360 }
1361
1362 /* now start counting all the messages that were queued before */
1363 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1364 var ro_integer rx_count := { 0, 0, 0, 0 };
1365 timer T := 2.0;
1366 T.start;
1367 alt {
1368 [] as_NsUdiCount(0, rx_count);
1369 [] as_NsUdiCount(1, rx_count);
1370 [] as_NsUdiCount(2, rx_count);
1371 [] as_NsUdiCount(3, rx_count);
1372 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1373 [] NS.receive(NsStatusIndication:?) { repeat; }
1374 [] NS.receive {
1375 setverdict(fail, "Rx unexpected NS");
1376 mtc.stop;
1377 }
1378 [] T.timeout {
1379 }
1380 }
1381 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1382 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1383 if (rx_count[i] == 0) {
1384 setverdict(fail, "Data not shared over all NSVC");
1385 }
1386 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001387}
1388
1389testcase TC_load_sharing_dl() runs on test_CT_NS
1390{
1391 var integer sgsn_idx, nri_idx;
1392 f_init();
1393 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1394 f_TC_load_sharing_dl(sgsn_idx);
1395 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001396 setverdict(pass);
1397}
1398private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1399 var NsUnitdataIndication udi;
1400 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1401 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1402 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1403 repeat;
1404 }
1405}
1406type component test_CT_NS extends test_CT {
1407 port NS_PT NS;
1408};
1409
1410
Harald Welte0e188242020-11-22 21:46:48 +01001411/***********************************************************************
1412 * PAGING PS procedure
1413 ***********************************************************************/
1414
1415private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1416 boolean use_sig := false)
1417runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1418 var template (value) PDU_BSSGP pdu_tx;
1419 var template (present) PDU_BSSGP pdu_rx;
1420 /* we always specify '0' as BVCI in the templates below, as we override it with
1421 * 'p4' later anyway */
1422 pdu_rx := tr_BSSGP_PS_PAGING(0);
1423 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1424 if (ispresent(g_pars.p_tmsi)) {
1425 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1426 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1427 } else {
1428 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1429 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1430 }
1431 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1432 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1433 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001434 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001435 } else {
1436 SGSN_SIG[sgsn_idx].send(pdu_tx);
1437 }
1438 return pdu_rx;
1439}
1440
1441/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1442 * specified PCU index */
1443private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1444 boolean use_sig := false,integer pcu_idx := 0)
1445runs on BSSGP_ConnHdlr {
1446 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001447 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001448 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1449 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1450 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1451 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1452 timer T := 2.0;
1453 T.start;
1454 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001455 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001456 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001457 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001458 repeat;
1459 }
1460 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1461 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1462 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001463 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001464 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001465 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001466 repeat;
1467 }
Harald Welte158becf2020-12-09 12:32:32 +01001468 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001469 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1470 }
Harald Welte158becf2020-12-09 12:32:32 +01001471 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001472 setverdict(fail, "Paging received on unexpected BVC");
1473 }
1474 [] any from PCU_SIG.receive(exp_rx) {
1475 setverdict(fail, "Paging received on unexpected BVC");
1476 }
Harald Welte158becf2020-12-09 12:32:32 +01001477 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001478 setverdict(fail, "Different Paging than expected received PTP BVC");
1479 }
1480 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1481 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1482 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001483 [not test_done] T.timeout {
1484 setverdict(fail, "Timeout waiting for paging");
1485 }
1486 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001487 }
1488}
1489
Harald Welte7462a592020-11-23 22:07:07 +01001490/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1491private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1492 boolean use_sig := false)
1493runs on BSSGP_ConnHdlr {
1494 var template (present) PDU_BSSGP exp_rx;
1495 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1496 /* Expect paging to propagate to no BSS */
1497 timer T := 2.0;
1498 T.start;
1499 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001500 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001501 setverdict(fail, "Paging received on unexpected BVC");
1502 }
1503 [] any from PCU_SIG.receive(exp_rx) {
1504 setverdict(fail, "Paging received on unexpected BVC");
1505 }
Harald Welte158becf2020-12-09 12:32:32 +01001506 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001507 setverdict(fail, "Different Paging received on PTP BVC");
1508 }
1509 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1510 setverdict(fail, "Different Paging received on SIGNALING BVC");
1511 }
1512 [] T.timeout {
1513 setverdict(pass);
1514 }
1515 }
1516}
1517
Harald Welte0e188242020-11-22 21:46:48 +01001518private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1519{
1520 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1521 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001522 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001523}
1524testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001525 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001526 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001527 f_cleanup();
1528}
1529
1530/* PS-PAGING on PTP-BVC for Location Area */
1531private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1532{
1533 var template (present) PDU_BSSGP exp_rx;
1534 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1535 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001536 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001537}
1538testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001539 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001540 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001541 f_cleanup();
1542}
1543
Harald Welte7462a592020-11-23 22:07:07 +01001544/* PS-PAGING on PTP-BVC for unknown Location Area */
1545private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1546{
1547 var GSM_Types.LocationAreaIdentification unknown_la := {
1548 mcc_mnc := '567F99'H,
1549 lac := 33333
1550 };
1551 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001552 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001553}
1554testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001555 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001556 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001557 f_cleanup();
1558}
1559
Harald Welte0e188242020-11-22 21:46:48 +01001560/* PS-PAGING on PTP-BVC for Routeing Area */
1561private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1562{
1563 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1564 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001565 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001566}
1567testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001568 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001569 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001570 f_cleanup();
1571}
1572
Harald Welte7462a592020-11-23 22:07:07 +01001573/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1574private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1575{
1576 var RoutingAreaIdentification unknown_ra := {
1577 lai := {
1578 mcc_mnc := '567F99'H,
1579 lac := 33333
1580 },
1581 rac := 254
1582 };
1583 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001584 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001585}
1586testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001587 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001588 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001589 f_cleanup();
1590}
1591
Harald Welte0e188242020-11-22 21:46:48 +01001592/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1593private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1594{
1595 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001596 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001597}
1598testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001599 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001600 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001601 f_cleanup();
1602}
1603
Harald Welteb5a04aa2021-01-16 13:04:40 +01001604
1605/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1606testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1607 f_init();
1608 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1609 f_cleanup();
1610}
1611
Harald Weltecf200072021-01-16 15:20:46 +01001612/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1613testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1614 f_init();
1615 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1616 f_cleanup();
1617}
1618
1619/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1620private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1621{
1622 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001623 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Weltecf200072021-01-16 15:20:46 +01001624 /* then simulate the PS-PAGING-REJECT from the PCU */
1625 f_send_paging_ps_rej(use_sig:=false);
1626}
1627testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1628 f_init();
1629 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1630 f_cleanup();
1631}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001632
Harald Welte7462a592020-11-23 22:07:07 +01001633/* PS-PAGING on PTP-BVC for unknown BVCI */
1634private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1635{
1636 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001637 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001638}
1639testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001640 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001641 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001642 f_cleanup();
1643}
1644
Harald Welte7595d562021-01-16 19:09:20 +01001645/* DUMMY PAGING PS on PTP BVC */
1646private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1647{
1648 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1649 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1650 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1651 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1652}
1653testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1654 f_init();
1655 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1656 f_cleanup();
1657}
1658
Harald Welte0e188242020-11-22 21:46:48 +01001659/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1660private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1661runs on BSSGP_ConnHdlr {
1662[] PCU_SIG[pcu_idx].receive(exp_rx) {
1663 if (ro_integer_contains(roi, pcu_idx)) {
1664 setverdict(fail, "Received multiple paging on same SIG BVC");
1665 }
1666 roi := roi & { pcu_idx };
1667 repeat;
1668 }
Harald Welte158becf2020-12-09 12:32:32 +01001669[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001670 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1671 }
1672[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1673 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1674 }
Harald Welte158becf2020-12-09 12:32:32 +01001675[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001676 setverdict(fail, "Different Paging than expected received PTP BVC");
1677 }
1678}
1679
1680type record of default ro_default;
1681
1682/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1683private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1684 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1685{
1686 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001687 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001688
1689 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1690 var ro_default defaults := {};
1691 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1692 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1693 defaults := defaults & { d };
1694 }
1695 f_sleep(2.0);
1696 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1697 deactivate(defaults[i]);
1698 }
1699 log("Paging received on PCU ", g_roi);
1700
1701 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1702 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1703 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1704 if (exp_on_i and not rx_on_i) {
1705 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1706 }
1707 if (not exp_on_i and rx_on_i) {
1708 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1709 }
1710 }
1711 setverdict(pass);
1712}
1713
Harald Weltecf200072021-01-16 15:20:46 +01001714/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1715private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1716{
1717 var template (value) PDU_BSSGP pdu_tx;
1718 var template (present) PDU_BSSGP exp_rx;
1719 var PDU_BSSGP pdu_rx;
1720 timer T := 5.0;
1721 var template (omit) GsmTmsi tmsi_int := omit;
1722
1723 if (ispresent(g_pars.p_tmsi)) {
1724 tmsi_int := oct2int(g_pars.p_tmsi);
1725 }
1726
1727 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1728 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1729
1730 if (use_sig) {
1731 PCU_SIG[pcu_idx].send(pdu_tx);
1732 } else {
1733 PCU_PTP[pcu_idx].send(pdu_tx);
1734 }
1735 T.start;
1736 alt {
1737 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1738 setverdict(pass);
1739 }
1740 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1741 setverdict(fail, "Unexpected PDU on SGSN");
1742 }
1743 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1744 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1745 }
1746 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1747 setverdict(pass);
1748 }
1749 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1750 setverdict(fail, "Unexpected PDU on SGSN");
1751 }
1752 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1753 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1754 }
1755 [] T.timeout {
1756 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1757 }
1758 }
1759}
1760
Harald Welte0e188242020-11-22 21:46:48 +01001761/* PS-PAGING on SIG-BVC for BSS Area */
1762private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1763{
1764 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001765 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001766}
1767testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001768 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001769 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001770 f_cleanup();
1771}
1772
1773/* PS-PAGING on SIG-BVC for Location Area */
1774private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1775{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001776 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001777 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, {0, 1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001778 /* Reset state */
1779 g_roi := {};
1780 /* Make LAC (13300) available on pcu index 2 */
1781 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001782 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001783}
1784testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001785 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001786 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001787 f_cleanup();
1788}
1789
Harald Welte7462a592020-11-23 22:07:07 +01001790/* PS-PAGING on SIG-BVC for unknown Location Area */
1791private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1792{
1793 var GSM_Types.LocationAreaIdentification unknown_la := {
1794 mcc_mnc := '567F99'H,
1795 lac := 33333
1796 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001797 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001798}
1799testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001800 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001801 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001802 f_cleanup();
1803}
1804
Harald Welte0e188242020-11-22 21:46:48 +01001805/* PS-PAGING on SIG-BVC for Routeing Area */
1806private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1807{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001808 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001809 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001810 g_roi := {};
1811 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001812 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {1, 2});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001813 g_roi := {};
1814 /* PCU index 2 has two matching BVCs with the RA ID */
1815 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001816 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), g_pars.sgsn_idx, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001817}
1818testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001819 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001820 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001821 f_cleanup();
1822}
1823
Harald Welte7462a592020-11-23 22:07:07 +01001824/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1825private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1826{
1827 var RoutingAreaIdentification unknown_ra := {
1828 lai := {
1829 mcc_mnc := '567F99'H,
1830 lac := 33333
1831 },
1832 rac := 254
1833 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001834 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001835}
1836testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001837 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001838 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001839 f_cleanup();
1840}
1841
Harald Welte0e188242020-11-22 21:46:48 +01001842/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1843private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1844{
Daniel Willmann43320442021-01-17 14:07:05 +01001845 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Welte0e188242020-11-22 21:46:48 +01001846}
1847testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001848 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001849 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001850 f_cleanup();
1851}
1852
Harald Welteb5a04aa2021-01-16 13:04:40 +01001853/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1854testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1855 f_init();
1856 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1857 f_cleanup();
1858}
1859
Harald Weltecf200072021-01-16 15:20:46 +01001860/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1861private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1862{
1863 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001864 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, {0});
Harald Weltecf200072021-01-16 15:20:46 +01001865 /* then simulate the PS-PAGING-REJECT from the PCU */
1866 f_send_paging_ps_rej(use_sig:=true);
1867
1868}
1869testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1870 f_init();
1871 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1872 f_cleanup();
1873}
1874
1875/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1876testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1877 f_init();
1878 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1879 f_cleanup();
1880}
1881
Harald Welte7462a592020-11-23 22:07:07 +01001882/* PS-PAGING on SIG-BVC for unknown BVCI */
1883private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1884{
Daniel Willmann2a330672021-01-18 18:50:02 +01001885 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001886}
1887testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001888 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001889 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001890 f_cleanup();
1891}
1892
Harald Welte7595d562021-01-16 19:09:20 +01001893/* DUMMY PAGING PS on SIG BVC */
1894private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1895{
1896 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1897 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1898 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1899 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1900}
1901testcase TC_dummy_paging_ps_sig() runs on test_CT {
1902 f_init();
1903 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1904 f_cleanup();
1905}
1906
Harald Welte7462a592020-11-23 22:07:07 +01001907
Harald Welte0e188242020-11-22 21:46:48 +01001908
1909/***********************************************************************
1910 * PAGING CS procedure
1911 ***********************************************************************/
1912
1913private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1914 boolean use_sig := false)
1915runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1916 var template (value) PDU_BSSGP pdu_tx;
1917 var template (present) PDU_BSSGP pdu_rx;
1918 /* we always specify '0' as BVCI in the templates below, as we override it with
1919 * 'p4' later anyway */
1920 pdu_rx := tr_BSSGP_CS_PAGING(0);
1921 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1922 if (ispresent(g_pars.p_tmsi)) {
1923 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1924 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1925 } else {
1926 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1927 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1928 }
1929 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1930 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1931 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001932 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001933 } else {
1934 SGSN_SIG[sgsn_idx].send(pdu_tx);
1935 }
1936 return pdu_rx;
1937}
1938
1939/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1940 * specified PCU index */
1941private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1942 boolean use_sig := false,integer pcu_idx := 0)
1943runs on BSSGP_ConnHdlr {
1944 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001945 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001946 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1947 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1948 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1949 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1950 timer T := 2.0;
1951 T.start;
1952 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001953 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001954 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001955 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001956 repeat;
1957 }
1958 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1959 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1960 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001961 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001962 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001963 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001964 repeat;
1965 }
Harald Welte158becf2020-12-09 12:32:32 +01001966 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001967 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1968 }
Harald Welte158becf2020-12-09 12:32:32 +01001969 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001970 setverdict(fail, "Paging received on unexpected BVC");
1971 }
1972 [] any from PCU_SIG.receive(exp_rx) {
1973 setverdict(fail, "Paging received on unexpected BVC");
1974 }
Harald Welte158becf2020-12-09 12:32:32 +01001975 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001976 setverdict(fail, "Different Paging than expected received PTP BVC");
1977 }
1978 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1979 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1980 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001981 [not test_done] T.timeout {
1982 setverdict(fail, "Timeout while waiting for paging")
1983 }
1984 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001985 }
1986}
1987
Harald Welte7462a592020-11-23 22:07:07 +01001988/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1989private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1990 boolean use_sig := false)
1991runs on BSSGP_ConnHdlr {
1992 var template (present) PDU_BSSGP exp_rx;
1993 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1994 /* Expect paging to propagate to no BSS */
1995 timer T := 2.0;
1996 T.start;
1997 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001998 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001999 setverdict(fail, "Paging received on unexpected BVC");
2000 }
2001 [] any from PCU_SIG.receive(exp_rx) {
2002 setverdict(fail, "Paging received on unexpected BVC");
2003 }
Harald Welte158becf2020-12-09 12:32:32 +01002004 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002005 setverdict(fail, "Different Paging received on PTP BVC");
2006 }
2007 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2008 setverdict(fail, "Different Paging received on SIGNALING BVC");
2009 }
2010 [] T.timeout {
2011 setverdict(pass);
2012 }
2013 }
2014}
2015
Harald Welte0e188242020-11-22 21:46:48 +01002016private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2017{
2018 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2019 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2020 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2021}
2022testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002023 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002024 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002025 f_cleanup();
2026}
2027
2028/* CS-PAGING on PTP-BVC for Location Area */
2029private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2030{
2031 var template (present) PDU_BSSGP exp_rx;
2032 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2033 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2034 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2035}
2036testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002037 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002038 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002039 f_cleanup();
2040}
2041
Harald Welte7462a592020-11-23 22:07:07 +01002042/* CS-PAGING on PTP-BVC for unknown Location Area */
2043private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2044{
2045 var GSM_Types.LocationAreaIdentification unknown_la := {
2046 mcc_mnc := '567F99'H,
2047 lac := 33333
2048 };
2049 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2050 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2051}
2052testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002053 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002054 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002055 f_cleanup();
2056}
2057
Harald Welte0e188242020-11-22 21:46:48 +01002058/* CS-PAGING on PTP-BVC for Routeing Area */
2059private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2060{
2061 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2062 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2063 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2064}
2065testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002066 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002067 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002068 f_cleanup();
2069}
2070
Harald Welte7462a592020-11-23 22:07:07 +01002071/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2072private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2073{
2074 var RoutingAreaIdentification unknown_ra := {
2075 lai := {
2076 mcc_mnc := '567F99'H,
2077 lac := 33333
2078 },
2079 rac := 254
2080 };
2081 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2082 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2083}
2084testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002085 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002086 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002087 f_cleanup();
2088}
2089
Harald Welte0e188242020-11-22 21:46:48 +01002090/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2091private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2092{
2093 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2094 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2095}
2096testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002097 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002098 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002099 f_cleanup();
2100}
2101
Harald Welte7462a592020-11-23 22:07:07 +01002102/* CS-PAGING on PTP-BVC for unknown BVCI */
2103private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2104{
2105 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2106 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2107}
2108testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002109 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002110 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002111 f_cleanup();
2112}
2113
Harald Welte0e188242020-11-22 21:46:48 +01002114/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2115private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2116 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2117{
2118 var template (present) PDU_BSSGP exp_rx;
2119 exp_rx := f_send_paging_cs(p4, 0, true);
2120
2121 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2122 var ro_default defaults := {};
2123 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2124 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2125 defaults := defaults & { d };
2126 }
2127 f_sleep(2.0);
2128 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2129 deactivate(defaults[i]);
2130 }
2131 log("Paging received on PCU ", g_roi);
2132
2133 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2134 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2135 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2136 if (exp_on_i and not rx_on_i) {
2137 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2138 }
2139 if (not exp_on_i and rx_on_i) {
2140 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2141 }
2142 }
2143 setverdict(pass);
2144}
2145
2146/* CS-PAGING on SIG-BVC for BSS Area */
2147private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2148{
2149 /* we expect the paging to arrive on all three NSE */
2150 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2151}
2152testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002153 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002154 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002155 f_cleanup();
2156}
2157
2158/* CS-PAGING on SIG-BVC for Location Area */
2159private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2160{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002161 /* The first LAC (13135) is shared by all three NSEs */
2162 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2163 /* Reset state */
2164 g_roi := {};
2165 /* Make LAC (13300) available on pcu index 2 */
2166 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2167 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 +01002168}
2169testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002170 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002171 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002172 f_cleanup();
2173}
2174
Harald Welte7462a592020-11-23 22:07:07 +01002175/* CS-PAGING on SIG-BVC for unknown Location Area */
2176private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2177{
2178 var GSM_Types.LocationAreaIdentification unknown_la := {
2179 mcc_mnc := '567F99'H,
2180 lac := 33333
2181 };
2182 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2183}
2184testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002185 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002186 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002187 f_cleanup();
2188}
2189
Harald Welte0e188242020-11-22 21:46:48 +01002190/* CS-PAGING on SIG-BVC for Routeing Area */
2191private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2192{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002193 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002194 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 +01002195 g_roi := {};
2196 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2197 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2198 g_roi := {};
2199 /* PCU index 2 has two matching BVCs with the RA ID */
2200 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2201 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 +01002202}
2203testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002204 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002205 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002206 f_cleanup();
2207}
2208
Harald Welte7462a592020-11-23 22:07:07 +01002209/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2210private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2211{
2212 var RoutingAreaIdentification unknown_ra := {
2213 lai := {
2214 mcc_mnc := '567F99'H,
2215 lac := 33333
2216 },
2217 rac := 254
2218 };
2219 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2220}
2221testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002222 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002223 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002224 f_cleanup();
2225}
2226
Harald Welte0e188242020-11-22 21:46:48 +01002227/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2228private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2229{
2230 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2231}
2232testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002233 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002234 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002235 f_cleanup();
2236}
2237
Harald Welte7462a592020-11-23 22:07:07 +01002238/* CS-PAGING on SIG-BVC for unknown BVCI */
2239private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2240{
2241 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2242}
2243testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002244 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002245 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002246 f_cleanup();
2247}
2248
Harald Welte4f91c3b2020-12-09 12:25:51 +01002249/***********************************************************************
2250 * FLUSH-LL procedure
2251 ***********************************************************************/
2252
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002253private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2254 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2255 var integer i;
2256 for (i := 0; i < 10; i := i+1) {
2257 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2258 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2259 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2260
2261 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2262
2263 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2264 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2265 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2266
2267 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2268 }
2269 setverdict(pass);
2270}
2271testcase TC_flush_ll() runs on test_CT
2272{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002273 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002274 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002275 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002276 f_cleanup();
2277}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002278
Harald Welte4f91c3b2020-12-09 12:25:51 +01002279/***********************************************************************
2280 * SGSN-INVOKE-TRACE procedure
2281 ***********************************************************************/
2282
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002283private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2284runs on GlobalTest_CT {
2285[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2286 if (ro_integer_contains(roi, pcu_idx)) {
2287 setverdict(fail, "Received multiple on same SIG BVC");
2288 }
2289 roi := roi & { pcu_idx };
2290 repeat;
2291 }
2292}
2293/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2294testcase TC_trace() runs on GlobalTest_CT
2295{
2296 var BSSGP_ConnHdlr vc_conn;
2297 f_init();
2298 f_global_init();
2299
2300 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2301 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2302
2303 var ro_default defaults := {};
2304 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2305 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2306 }
2307 G_SGSN[0].send(pdu_tx);
2308 f_sleep(2.0);
2309 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2310 deactivate(defaults[i]);
2311 }
2312
2313 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2314 if (not ro_integer_contains(g_roi, i)) {
2315 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2316 }
2317 }
2318 setverdict(pass);
2319
2320 f_cleanup();
2321}
2322
Harald Welte4f91c3b2020-12-09 12:25:51 +01002323/***********************************************************************
2324 * LLC-DISCARDED procedure
2325 ***********************************************************************/
2326
Harald Weltec0351d12020-11-27 22:49:02 +01002327private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2328 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2329
2330 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2331 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2332 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2333
2334 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2335
2336 setverdict(pass);
2337}
2338/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2339testcase TC_llc_discarded() runs on test_CT
2340{
Harald Weltec0351d12020-11-27 22:49:02 +01002341 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002342 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002343 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002344 f_cleanup();
2345}
2346
Harald Welte4f91c3b2020-12-09 12:25:51 +01002347/***********************************************************************
2348 * OVERLOAD procedure
2349 ***********************************************************************/
2350
Harald Weltef20af412020-11-28 16:11:11 +01002351/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2352testcase TC_overload() runs on GlobalTest_CT
2353{
2354 f_init();
2355 f_global_init();
2356
2357 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2358 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2359
2360 var ro_default defaults := {};
2361 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2362 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2363 }
2364 G_SGSN[0].send(pdu_tx);
2365 f_sleep(2.0);
2366 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2367 deactivate(defaults[i]);
2368 }
2369
2370 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2371 if (not ro_integer_contains(g_roi, i)) {
2372 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2373 }
2374 }
2375 setverdict(pass);
2376
2377 f_cleanup();
2378}
2379
Harald Welte4f91c3b2020-12-09 12:25:51 +01002380/***********************************************************************
2381 * BVC-BLOCK / BVC-UNBLOCK procedure
2382 ***********************************************************************/
2383
Harald Welte239aa502020-11-24 23:14:20 +01002384private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2385{
2386 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2387 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2388 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2389
2390 SGSN_MGMT.clear;
2391 PCU_MGMT.clear;
2392
2393 /* block the PTP BVC from the PCU side */
2394 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2395 /* expect state on both PCU and SGSN side to change */
2396 interleave {
2397 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2398 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2399 }
2400 setverdict(pass);
2401}
2402testcase TC_bvc_block_ptp() runs on test_CT
2403{
2404 f_init();
2405 f_sleep(1.0);
2406 f_block_ptp_bvc_from_pcu(0, 0);
2407 f_cleanup();
2408}
2409
2410private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2411{
2412 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2413 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2414 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2415
2416 SGSN_MGMT.clear;
2417 PCU_MGMT.clear;
2418
2419 /* block the PTP BVC from the PCU side */
2420 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2421 /* expect state on both PCU and SGSN side to change */
2422 interleave {
2423 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2424 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2425 }
2426 setverdict(pass);
2427}
2428testcase TC_bvc_unblock_ptp() runs on test_CT
2429{
2430 f_init();
2431 f_sleep(1.0);
2432 f_block_ptp_bvc_from_pcu(0, 0);
2433 f_sleep(1.0);
2434 f_unblock_ptp_bvc_from_pcu(0, 0);
2435 f_cleanup();
2436}
2437
Harald Welte4f91c3b2020-12-09 12:25:51 +01002438/***********************************************************************
2439 * BVC-RESET procedure
2440 ***********************************************************************/
2441
Harald Welte60a8ec72020-11-25 17:12:53 +01002442private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2443[] pt.receive(BssgpStatusIndication:?) { repeat; }
2444}
2445private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2446 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2447 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2448 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2449 }
2450 }
2451 return null;
2452}
2453private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2454{
2455 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2456 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2457 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2458 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2459 var default d;
2460
2461 SGSN_MGMT.clear;
2462 PCU_MGMT.clear;
2463
2464 /* block the PTP BVC from the PCU side */
2465 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2466 /* expect state on both PCU and SGSN side to change */
2467 d := activate(as_ignore_status(SGSN_MGMT));
2468 interleave {
2469 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2470 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2471 }
2472 deactivate(d);
2473 setverdict(pass);
2474}
2475/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2476testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2477{
2478 f_init();
2479 f_sleep(3.0);
2480 f_reset_ptp_bvc_from_pcu(0, 0);
2481 f_cleanup();
2482}
2483
Harald Welte16786e92020-11-27 19:11:56 +01002484private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2485runs on test_CT {
2486 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2487 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2488 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002489 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002490 }
2491}
2492/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2493testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2494
2495 f_init();
2496 f_sleep(3.0);
2497
2498 /* Start BVC-RESET procedure for BVCI=0 */
2499 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2500
2501 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2502 var ro_default defaults := {};
2503 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2504 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2505 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2506 defaults := defaults & { d };
2507 }
2508
2509 timer T := 3.0;
2510 T.start;
2511 alt {
2512 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2513 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2514 }
2515 [] T.timeout;
2516 }
2517
2518 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2519 deactivate(defaults[i]);
2520 }
2521
2522 /* check if BVC-block was received on all expected BVC */
2523 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2524 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2525 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2526 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2527 }
2528 }
2529
2530 /* check if BVC-block was not received on any unexpected BVC is not required as
2531 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002532 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002533 f_cleanup();
2534}
2535
Harald Welte60a8ec72020-11-25 17:12:53 +01002536private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2537{
2538 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2539 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2540 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2541 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2542 var default d;
2543
2544 SGSN_MGMT.clear;
2545 PCU_MGMT.clear;
2546
2547 /* block the PTP BVC from the PCU side */
2548 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2549 /* expect state on both PCU and SGSN side to change */
2550 d := activate(as_ignore_status(PCU_MGMT));
2551 interleave {
2552 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2553 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2554 }
2555 deactivate(d);
2556 setverdict(pass);
2557}
2558/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2559testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2560{
2561 f_init();
2562 f_sleep(3.0);
2563 f_reset_ptp_bvc_from_sgsn(0, 0);
2564 f_cleanup();
2565}
2566
Daniel Willmannef7015f2021-01-08 00:43:56 +01002567private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2568 [] pt.receive {repeat; }
2569}
2570
Harald Welte16786e92020-11-27 19:11:56 +01002571private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2572runs on test_CT {
2573 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2574 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2575 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002576 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002577 }
2578}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002579
Harald Welte16786e92020-11-27 19:11:56 +01002580/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2581testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2582
2583 f_init();
2584 f_sleep(3.0);
2585
Daniel Willmannef7015f2021-01-08 00:43:56 +01002586 SGSN_MGMT.clear;
2587 PCU_MGMT.clear;
2588
Harald Welte16786e92020-11-27 19:11:56 +01002589 /* Start BVC-RESET procedure for BVCI=0 */
2590 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2591
Daniel Willmannef7015f2021-01-08 00:43:56 +01002592 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2593 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2594 * the port and a different message sits at the front we wait forever and fail the test.
2595 */
2596 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2597
Harald Welte16786e92020-11-27 19:11:56 +01002598 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002599 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2600 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2601 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2602 defaults := defaults & { d };
2603 }
2604
2605 f_sleep(3.0);
2606
2607 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2608 deactivate(defaults[i]);
2609 }
2610
2611 /* check if BVC-block was received on all expected BVC */
2612 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2613 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2614 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2615 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2616 }
2617 }
2618
2619 /* check if BVC-block was not received on any unexpected BVC is not required as
2620 * such a message would basically run into 'no matching clause' */
2621
2622 f_cleanup();
2623}
2624
Harald Welte299aa482020-12-09 15:10:55 +01002625/***********************************************************************
2626 * FLOW-CONTROL-BVC procedure
2627 ***********************************************************************/
2628
2629private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2630 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2631runs on GlobalTest_CT {
2632 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2633 roi := roi & { sgsn_idx };
2634 if (ispresent(tx_reply)) {
2635 G_SGSN[sgsn_idx].send(tx_reply);
2636 }
Harald Welte5fb01742021-01-15 21:07:52 +01002637 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002638 }
2639}
2640/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2641testcase TC_fc_bvc() runs on GlobalTest_CT
2642{
2643 f_init();
2644 f_global_init_ptp();
2645
2646 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2647 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2648 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2649 var template (omit) PDU_BSSGP ack_tx :=
2650 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2651
2652 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2653 G_PCU[0].send(pdu_tx);
2654
2655 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2656 var ro_default defaults := {};
2657 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2658 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2659 defaults := defaults & { d };
2660 }
2661
2662 f_sleep(3.0);
2663
2664 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2665 deactivate(defaults[i]);
2666 }
2667
2668 /* check if BVC-block was received on all expected BVC */
2669 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2670 if (not ro_integer_contains(g_roi, i)) {
2671 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2672 }
2673 }
2674
2675 /* Expect ACK on PCU side */
2676 G_PCU[0].receive(ack_tx);
2677
2678 setverdict(pass);
2679
2680 f_cleanup();
2681}
2682
Harald Weltecc3894b2020-12-09 16:50:12 +01002683/***********************************************************************
2684 * FLOW-CONTROL-MS procedure
2685 ***********************************************************************/
2686
2687private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2688 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2689
2690 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2691 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2692 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2693 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2694
2695 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2696 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2697
2698 setverdict(pass);
2699}
2700/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2701testcase TC_fc_ms() runs on test_CT
2702{
Harald Weltecc3894b2020-12-09 16:50:12 +01002703 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002704 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002705 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002706 f_cleanup();
2707}
2708
Harald Welted6f89812021-01-16 18:57:49 +01002709/***********************************************************************
2710 * MS-REGISTRATION ENQUIRY procedure
2711 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002712
Harald Welted6f89812021-01-16 18:57:49 +01002713private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2714{
2715 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2716 f_sgsn2pcu(ts_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), tr_BSSGP_MS_REW_ENQ_RESP(g_pars.imsi, omit), use_sig := true);
2717}
2718testcase TC_ms_reg_enq() runs on test_CT
2719{
2720 f_init();
2721 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2722 f_cleanup();
2723}
Harald Welte299aa482020-12-09 15:10:55 +01002724
Harald Weltef86f1852021-01-16 21:56:17 +01002725/***********************************************************************
2726 * RIM (RAN Information Management)
2727 ***********************************************************************/
2728
2729/* Our tests here are rather synthetic, as they don't reflect normal message flows
2730 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2731 matter as gbproxy is not concerned with anything but the source / destination routing
2732 information */
2733
2734/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2735 one here of which we know it is not used among the [simulated] PCUs */
2736const BssgpCellId cell_id_sgsn := {
2737 ra_id := {
2738 lai := {
2739 mcc_mnc := c_mcc_mnc,
2740 lac := 65534
2741 },
2742 rac := 0
2743 },
2744 cell_id := 65533
2745};
2746
2747/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2748friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2749 integer pcu_idx := 0) runs on GlobalTest_CT {
2750 var PDU_BSSGP rx;
2751 timer T := 1.0;
2752
2753 RIM_PCU[pcu_idx].send(tx);
2754 T.start;
2755 alt {
2756 [] any from RIM_SGSN.receive(exp_rx) {
2757 setverdict(pass);
2758 }
2759 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2760 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2761 mtc.stop;
2762 }
2763 [] T.timeout {
2764 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2765 mtc.stop;
2766 }
2767 }
2768}
2769
2770/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2771friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2772 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2773 var PDU_BSSGP rx;
2774 timer T := 1.0;
2775
2776 RIM_SGSN[sgsn_idx].send(tx);
2777 T.start;
2778 alt {
2779 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2780 setverdict(pass);
2781 }
2782 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
2783 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
2784 mtc.stop;
2785 }
2786 [] T.timeout {
2787 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
2788 mtc.stop;
2789 }
2790 }
2791}
2792
2793/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2794friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2795 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2796 var integer rx_idx;
2797 var PDU_BSSGP rx;
2798 timer T := 1.0;
2799
2800 RIM_PCU[src_pcu_idx].send(tx);
2801 T.start;
2802 alt {
2803 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2804 setverdict(pass);
2805 }
2806 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2807 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2808 }
2809 [] any from RIM_SGSN.receive(exp_rx) {
2810 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2811 }
2812 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2813 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2814 mtc.stop;
2815 }
2816 [] T.timeout {
2817 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2818 mtc.stop;
2819 }
2820 }
2821}
2822
2823
2824type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2825
2826/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2827 each SGSN */
2828private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2829{
2830 var integer sgsn_idx, pcu_idx, bvc_idx;
2831 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2832 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2833 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2834 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2835 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2836 }
2837 }
2838 }
2839}
2840
2841/* RAN-INFORMATION-REQUEST */
2842private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2843runs on GlobalTest_CT
2844{
2845 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2846 var template (value) RIM_Routing_Information ri_pcu;
2847 var template (value) RIM_Routing_Information ri_sgsn;
2848 var template (value) RAN_Information_Request_RIM_Container cont;
2849
2850 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2851 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2852 cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2853 ts_RIM_Sequence_Number(0),
2854 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2855 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2856 tr_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2857 pcu_idx);
2858 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2859 tr_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2860 sgsn_idx, pcu_idx);
2861}
2862testcase TC_rim_info_req() runs on GlobalTest_CT
2863{
2864 f_init();
2865 f_global_init();
2866 f_rim_iterator(refers(f_TC_rim_info_req));
2867 f_cleanup();
2868}
2869
2870/* RAN-INFORMATION */
2871private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2872runs on GlobalTest_CT
2873{
2874 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2875 var template (value) RIM_Routing_Information ri_pcu;
2876 var template (value) RIM_Routing_Information ri_sgsn;
2877 var template (value) RAN_Information_RIM_Container cont;
2878
2879 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2880 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2881 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2882 ts_RIM_Sequence_Number(0),
2883 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2884 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2885 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2886 pcu_idx);
2887 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2888 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2889 sgsn_idx, pcu_idx);
2890}
2891testcase TC_rim_info() runs on GlobalTest_CT
2892{
2893 f_init();
2894 f_global_init();
2895 f_rim_iterator(refers(f_TC_rim_info));
2896 f_cleanup();
2897}
2898
2899/* RAN-INFORMATION-ACK */
2900private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2901runs on GlobalTest_CT
2902{
2903 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2904 var template (value) RIM_Routing_Information ri_pcu;
2905 var template (value) RIM_Routing_Information ri_sgsn;
2906 var template (value) RAN_Information_Ack_RIM_Container cont;
2907
2908 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2909 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2910 cont := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2911 ts_RIM_Sequence_Number(0));
2912 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2913 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2914 pcu_idx);
2915 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2916 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2917 sgsn_idx, pcu_idx);
2918}
2919testcase TC_rim_info_ack() runs on GlobalTest_CT
2920{
2921 f_init();
2922 f_global_init();
2923 f_rim_iterator(refers(f_TC_rim_info_ack));
2924 f_cleanup();
2925}
2926
2927/* RAN-INFORMATION-ERROR */
2928private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2929runs on GlobalTest_CT
2930{
2931 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2932 var template (value) RIM_Routing_Information ri_pcu;
2933 var template (value) RIM_Routing_Information ri_sgsn;
2934 var template (value) RAN_Information_Error_RIM_Container cont;
2935
2936 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2937 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2938 cont := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2939 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
2940 omit, valueof(t_BVC_UNBLOCK(23)));
2941 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2942 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2943 pcu_idx);
2944 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2945 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2946 sgsn_idx, pcu_idx);
2947}
2948testcase TC_rim_info_error() runs on GlobalTest_CT
2949{
2950 f_init();
2951 f_global_init();
2952 f_rim_iterator(refers(f_TC_rim_info_error));
2953 f_cleanup();
2954}
2955
2956/* RAN-INFORMATION-APPLICATION-ERROR */
2957private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2958runs on GlobalTest_CT
2959{
2960 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2961 var template (value) RIM_Routing_Information ri_pcu;
2962 var template (value) RIM_Routing_Information ri_sgsn;
2963 var template (value) Application_Error_Container app_cont;
2964 var template (value) RAN_Information_Application_Error_RIM_Container cont;
2965
2966 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2967 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2968 app_cont := tsu_Application_Error_Container_NACC(cell_id, 23,
2969 tsu_Application_Container_IE_NACC_req(cell_id));
2970 cont := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2971 ts_RIM_Sequence_Number(0),
2972 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
2973 omit, app_cont);
2974 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2975 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2976 pcu_idx);
2977 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2978 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2979 sgsn_idx, pcu_idx);
2980}
2981testcase TC_rim_info_app_error() runs on GlobalTest_CT
2982{
2983 f_init();
2984 f_global_init();
2985 f_rim_iterator(refers(f_TC_rim_info_app_error));
2986 f_cleanup();
2987}
2988
2989/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
2990private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
2991 integer dst_pcu_idx, integer dst_bvc_idx)
2992runs on GlobalTest_CT
2993{
2994 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
2995 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
2996 var template (value) RIM_Routing_Information ri_pcu_src;
2997 var template (value) RIM_Routing_Information ri_pcu_dst;
2998 var template (value) RAN_Information_RIM_Container cont;
2999
3000 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3001 dst_pcu_idx, "][", dst_bvc_idx, "]");
3002
3003 ri_pcu_src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3004 t_RIM_Routing_Address_cid(cell_id_src));
3005 ri_pcu_dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3006 t_RIM_Routing_Address_cid(cell_id_dst));
3007 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3008 ts_RIM_Sequence_Number(0),
3009 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3010 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3011 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3012 src_pcu_idx, dst_pcu_idx);
3013}
3014testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3015{
3016 var integer src_pcu_idx, dst_pcu_idx;
3017 var integer src_bvc_idx, dst_bvc_idx;
3018 f_init();
3019 f_global_init();
3020
3021 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3022 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3023 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3024 if (dst_pcu_idx == src_pcu_idx) {
3025 continue;
3026 }
3027
3028 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3029dst_bvc_idx := dst_bvc_idx + 1) {
3030 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3031 }
3032 }
3033 }
3034 }
3035
3036 f_cleanup();
3037}
3038
Harald Welte04358652021-01-17 13:48:13 +01003039/***********************************************************************
3040 * STATUS handling
3041 ***********************************************************************/
3042
3043/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3044
3045/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3046private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3047{
3048 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3049 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3050}
3051
3052/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3053private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3054{
3055 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3056 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3057}
3058
3059/* STATUS in uplink direction; expect routing by its NRI */
3060private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3061runs on GlobalTest_CT
3062{
3063 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3064 var template (present) PDU_BSSGP exp_rx :=
3065 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3066 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3067
3068 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3069}
3070
3071/* STATUS in uplink direction; expect routing by its NRI */
3072private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3073runs on GlobalTest_CT
3074{
3075 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3076 var template (present) PDU_BSSGP exp_rx :=
3077 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3078 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3079
3080 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3081}
3082
3083/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3084testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3085{
3086 var integer sgsn_idx, nri_idx;
3087
3088 f_init();
3089 f_global_init();
3090
3091 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3092 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3093 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3094 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3095 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3096
3097 f_TC_status_ul(0, sgsn_idx, inner);
3098 }
3099 }
3100
3101 f_cleanup();
3102}
3103
3104/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3105testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3106{
3107 var integer sgsn_idx, nri_idx;
3108
3109 f_init();
3110 f_global_init();
3111
3112 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3113 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3114 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3115 const hexstring imsi := '001010123456789'H
3116 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3117 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3118 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3119 f_TC_status_ul(0, sgsn_idx, inner);
3120 }
3121 }
3122
3123 f_cleanup();
3124}
3125
3126
3127/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3128testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3129{
3130 var integer sgsn_idx, nri_idx;
3131
3132 f_init();
3133 f_global_init_ptp();
3134
3135 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3136 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3137 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3138 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3139 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3140
3141 f_TC_status_ul(0, sgsn_idx, inner);
3142 }
3143 }
3144
3145 f_cleanup();
3146}
3147
3148/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3149testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3150{
3151 var integer sgsn_idx, nri_idx;
3152
3153 f_init();
3154 f_global_init_ptp();
3155
3156 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3157 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3158 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3159 const hexstring imsi := '001010123456789'H
3160 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3161 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3162 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3163 f_TC_status_ul(0, sgsn_idx, inner);
3164 }
3165 }
3166
3167 f_cleanup();
3168}
3169
3170/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3171testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3172{
3173 var integer sgsn_idx, pcu_idx, bvc_idx;
3174
3175 f_init();
3176 f_global_init();
3177
3178 /* test each BVC in each PCU from each SGSN */
3179 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3180 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3181 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3182 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3183 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3184 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3185 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3186 }
3187 }
3188 }
3189
3190 f_cleanup();
3191}
3192
3193/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3194testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3195{
3196 var integer sgsn_idx, pcu_idx, bvc_idx;
3197
3198 f_init();
3199 f_global_init_ptp();
3200
3201 /* test each BVC in each PCU from each SGSN */
3202 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3203 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3204 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3205 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3206 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3207 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3208
3209 /* some uplink PDU occurring on PTP-BVC */
3210 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3211 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3212 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3213 }
3214 }
3215 }
3216
3217 f_cleanup();
3218}
3219
3220/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3221/* TODO: test case for UL-STATUS(PAGING-by-IMSI) after sending an actual PAGIN-by-IMSI in DL first */
Harald Weltef86f1852021-01-16 21:56:17 +01003222
Daniel Willmann423d8f42020-09-08 18:58:22 +02003223control {
3224 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003225 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003226 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003227 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003228 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003229 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003230 execute( TC_radio_status_tmsi() );
3231 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003232 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003233 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003234 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003235 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003236 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003237 execute( TC_bvc_block_ptp() );
3238 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003239 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003240 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003241 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003242 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003243 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003244 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3245 execute( TC_load_sharing_dl() );
3246 }
Harald Welte0e188242020-11-22 21:46:48 +01003247
3248 /* PAGING-PS over PTP BVC */
3249 execute( TC_paging_ps_ptp_bss() );
3250 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003251 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003252 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003253 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003254 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003255 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003256 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003257 execute( TC_paging_ps_reject_ptp_bvci() );
3258 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003259 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003260
3261 /* PAGING-PS over SIG BVC */
3262 execute( TC_paging_ps_sig_bss() );
3263 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003264 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003265 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003266 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003267 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003268 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003269 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003270 execute( TC_paging_ps_reject_sig_bvci() );
3271 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003272 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003273
3274 /* PAGING-CS over PTP BVC */
3275 execute( TC_paging_cs_ptp_bss() );
3276 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003277 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003278 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003279 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003280 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003281 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003282
3283 /* PAGING-CS over SIG BVC */
3284 execute( TC_paging_cs_sig_bss() );
3285 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003286 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003287 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003288 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003289 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003290 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003291
Harald Weltef86f1852021-01-16 21:56:17 +01003292 /* RAN Information Management */
3293 execute( TC_rim_info_req() );
3294 execute( TC_rim_info() );
3295 execute( TC_rim_info_ack() );
3296 execute( TC_rim_info_error() );
3297 execute( TC_rim_info_app_error() );
3298 execute( TC_rim_info_pcu2pcu() );
3299
Harald Welte0e188242020-11-22 21:46:48 +01003300
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003301 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003302 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003303 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003304 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003305
3306 /* Uplink STATUS */
3307 execute( TC_status_sig_ul_tlli() );
3308 execute( TC_status_sig_ul_tmsi() );
3309 execute( TC_status_ptp_ul_tlli() );
3310 execute( TC_status_ptp_ul_tmsi() );
3311
3312 /* Downlink STATUS */
3313 execute( TC_status_sig_dl_bvci() );
3314 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003315}
3316
3317
3318}