blob: fa04190dccba4c4862647edfab404b9e7d8d04df [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,
68 local_ip := "127.0.0.1",
69 remote_udp_port := 23000,
70 remote_ip := "127.0.0.1"
71 }
72 },
73 nsvci := 101
74 }
75 }
Harald Welteb978ed62020-12-12 14:01:11 +010076 }, {
77 nsei := 102,
78 role_sgsn := true,
79 handle_sns := false,
80 nsvc := {
81 {
82 provider := {
83 ip := {
84 address_family := AF_INET,
85 local_udp_port := 8888,
86 local_ip := "127.0.0.1",
87 remote_udp_port := 23000,
88 remote_ip := "127.0.0.1"
89 }
90 },
91 nsvci := 102
92 }
93 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020094 }
95 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010096 /* BSS NSEI start at 2000 + x
97 * NSVCI start from value of NSEI + 100
98 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010099 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200100 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100101 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200102 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100103 handle_sns := false,
104 nsvc := {
105 {
106 provider := {
107 ip := {
108 address_family := AF_INET,
109 local_udp_port := 21010,
110 local_ip := "127.0.0.1",
111 remote_udp_port := 23000,
112 remote_ip := "127.0.0.1"
113 }
114 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100115 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100116 }
117 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200118 },
119 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100120 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200121 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100122 handle_sns := false,
123 nsvc := {
124 {
125 provider := {
126 ip := {
127 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100128 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100129 local_ip := "127.0.0.1",
130 remote_udp_port := 23000,
131 remote_ip := "127.0.0.1"
132 }
133 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100134 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100135 }
136 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200137 },
138 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100139 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200140 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100141 handle_sns := false,
142 nsvc := {
143 {
144 provider := {
145 ip := {
146 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100147 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100148 local_ip := "127.0.0.1",
149 remote_udp_port := 23000,
150 remote_ip := "127.0.0.1"
151 }
152 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100153 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100154 }
155 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200156 }
157 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100158 /* BVCI are NSEI*10 + x
159 * The first NSE only has one BVC, the second one 2 and so on
160 * The Cell ID is BVCI + 10000
161 * LAC/RAC are configured in such a way that:
162 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
163 * LAC 13300 is present twice in NSE(2003)
164 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
165 * RAI 13300-0 is present twice in NSE(2003)
166 */
Harald Welte6d63f742020-11-15 19:44:04 +0100167 BssgpConfigs mp_gbconfigs := {
168 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100169 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100170 sgsn_role := false,
171 bvc := {
172 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100173 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100174 cell_id := {
175 ra_id := {
176 lai := {
177 mcc_mnc := c_mcc_mnc,
178 lac := 13135
179 },
180 rac := 0
181 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100182 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100183 },
184 depth := BSSGP_DECODE_DEPTH_BSSGP,
185 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
186 }
187 }
188 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100189 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100190 sgsn_role := false,
191 bvc := {
192 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100193 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100194 cell_id := {
195 ra_id := {
196 lai := {
197 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100198 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100199 },
Harald Welte0e188242020-11-22 21:46:48 +0100200 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100201 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100202 cell_id := 30021
203 },
204 depth := BSSGP_DECODE_DEPTH_BSSGP,
205 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
206 },
207 {
208 bvci := 20022,
209 cell_id := {
210 ra_id := {
211 lai := {
212 mcc_mnc := c_mcc_mnc,
213 lac := 13135
214 },
215 rac := 2
216 },
217 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100218 },
219 depth := BSSGP_DECODE_DEPTH_BSSGP,
220 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
221 }
222 }
223 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100224 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100225 sgsn_role := false,
226 bvc := {
227 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100228 bvci := 20031,
229 cell_id := {
230 ra_id := {
231 lai := {
232 mcc_mnc := c_mcc_mnc,
233 lac := 13135
234 },
235 rac := 1
236 },
237 cell_id := 30031
238 },
239 depth := BSSGP_DECODE_DEPTH_BSSGP,
240 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
241 },
242 {
243 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100244 cell_id := {
245 ra_id := {
246 lai := {
247 mcc_mnc := c_mcc_mnc,
248 lac := 13300
249 },
250 rac := 0
251 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100252 cell_id := 30032
253 },
254 depth := BSSGP_DECODE_DEPTH_BSSGP,
255 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
256 },
257 {
258 bvci := 20033,
259 cell_id := {
260 ra_id := {
261 lai := {
262 mcc_mnc := c_mcc_mnc,
263 lac := 13300
264 },
265 rac := 0
266 },
267 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100268 },
269 depth := BSSGP_DECODE_DEPTH_BSSGP,
270 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
271 }
272 }
273 }
274 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200275};
276
Daniel Willmann423d8f42020-09-08 18:58:22 +0200277type record GbInstance {
278 NS_CT vc_NS,
279 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100280 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200281 BssgpConfig cfg
282};
Harald Welte67dc8c22020-11-17 18:32:29 +0100283type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200284
285const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100286type record of GbInstance GbInstances;
287type record of BssgpConfig BssgpConfigs;
288type record of NSConfiguration NSConfigurations;
289type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200290
Harald Welteb978ed62020-12-12 14:01:11 +0100291const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200292
293type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100294 var GbInstances g_pcu;
295 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200296
297 port BSSGP_CT_PROC_PT PROC;
298
Harald Weltefbae83f2020-11-15 23:25:55 +0100299 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
300 port BSSGP_BVC_MGMT_PT PCU_MGMT;
301
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302 port TELNETasp_PT GBPVTY;
303
304 var boolean g_initialized := false;
305 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100306
307 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100308 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200309};
310
311type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100312 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100313 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200314 port BSSGP_PT PCU_SIG[NUM_PCU];
315 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100316 /* component reference to the component to which we're currently connected */
317 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100318 /* BSSGP BVC configuration of the component to which we're currently connected */
319 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100320
321 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100322 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200323 port BSSGP_PT SGSN_SIG[NUM_SGSN];
324 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100325 /* component reference to the component to which we're currently connected */
326 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200327
328 var BSSGP_ConnHdlrPars g_pars;
329 timer g_Tguard;
330 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100331
332 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200333}
334
335type record SGSN_ConnHdlrNetworkPars {
336 boolean expect_ptmsi,
337 boolean expect_auth,
338 boolean expect_ciph
339};
340
341type record BSSGP_ConnHdlrPars {
342 /* IMEI of the simulated ME */
343 hexstring imei,
344 /* IMSI of the simulated MS */
345 hexstring imsi,
346 /* MSISDN of the simulated MS (probably unused) */
347 hexstring msisdn,
348 /* P-TMSI allocated to the simulated MS */
349 OCT4 p_tmsi optional,
350 OCT3 p_tmsi_sig optional,
351 /* TLLI of the simulated MS */
352 OCT4 tlli,
353 OCT4 tlli_old optional,
354 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100355 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100356 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100357 /* The SGSN index to be used within the test */
358 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200359 float t_guard
360};
361
Harald Welte04358652021-01-17 13:48:13 +0100362private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
363{
364 var integer i;
365
366 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
367 if (gbi.cfg.bvc[i].bvci == bvci) {
368 return i;
369 }
370 }
371 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
372 return -1;
373}
374
Daniel Willmann423d8f42020-09-08 18:58:22 +0200375private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
376 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
377 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
378
379 var RoutingAreaIdentificationV ret := {
380 mccDigit1 := mcc_mnc[0],
381 mccDigit2 := mcc_mnc[1],
382 mccDigit3 := mcc_mnc[2],
383 mncDigit3 := mcc_mnc[3],
384 mncDigit1 := mcc_mnc[4],
385 mncDigit2 := mcc_mnc[5],
386 lac := int2oct(cell_id.ra_id.lai.lac, 16),
387 rac := int2oct(cell_id.ra_id.rac, 8)
388 }
389 return ret;
390};
391
Harald Welte95339432020-12-02 18:50:52 +0100392private function f_fix_create_cb(inout BssgpConfig cfg)
393{
394 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
395 if (not isbound(cfg.bvc[i].create_cb)) {
396 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
397 }
398 }
399}
400
Daniel Willmann423d8f42020-09-08 18:58:22 +0200401private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100402 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
403 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
404 gb.vc_NS := NS_CT.create(ns_id);
405 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200406 /* connect lower end of BSSGP emulation with NS upper port */
407 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
408
Harald Welteb419d0e2020-11-16 16:45:05 +0100409 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
410 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200411
412 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100413 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200414 connect(self:PROC, gb.vc_BSSGP:PROC);
415 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
416 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100417 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100418 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200419 }
Harald Welteb978ed62020-12-12 14:01:11 +0100420 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100421 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200422}
423
424private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100425 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
426 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
427 gb.vc_NS := NS_CT.create(ns_id);
428 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200429 /* connect lower end of BSSGP emulation with NS upper port */
430 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
431
Harald Welteb419d0e2020-11-16 16:45:05 +0100432 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
433 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200434
435 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100436 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200437 connect(self:PROC, gb.vc_BSSGP:PROC);
438 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
439 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100440 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100441 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200442 }
Harald Welteb978ed62020-12-12 14:01:11 +0100443 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100444 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200445}
446
447
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100448private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
449 gb.vc_NS.stop;
450 gb.vc_BSSGP.stop;
451
452 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
453 gb.vc_BSSGP_BVC[i].stop;
454 }
455}
456
Daniel Willmann423d8f42020-09-08 18:58:22 +0200457private function f_init_vty() runs on test_CT {
458 map(self:GBPVTY, system:GBPVTY);
459 f_vty_set_prompts(GBPVTY);
460 f_vty_transceive(GBPVTY, "enable");
461}
462
Harald Weltefbae83f2020-11-15 23:25:55 +0100463type record of integer ro_integer;
464
465private function ro_integer_contains(ro_integer r, integer x) return boolean {
466 for (var integer j := 0; j < lengthof(r); j := j+1) {
467 if (r[j] == x) {
468 return true;
469 }
470 }
471 return false;
472}
473
Harald Welteb978ed62020-12-12 14:01:11 +0100474private type record of ro_integer roro_integer;
475
476/* count the number of unblocked BVCI for each SGSN NSE */
477private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
478runs on test_CT {
479 var BssgpStatusIndication bsi;
480 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
481 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
482 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
483 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
484 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
485 repeat;
486 }
487 }
488 }
489}
490
Harald Welte425d3762020-12-09 14:33:18 +0100491function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100492 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100493 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200494 var integer i;
495
496 if (g_initialized == true) {
497 return;
498 }
499 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200500
Harald Welte425d3762020-12-09 14:33:18 +0100501 g_Tguard.start(t_guard);
502 activate(as_gTguard(g_Tguard));
503
Harald Welteb978ed62020-12-12 14:01:11 +0100504 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100505 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
506 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100507 /* make sure all have a proper crate_cb, which cannot be specified in config file */
508 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100509 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100510 bvcs := bvcs & g_pcu[i].cfg.bvc;
511 }
512
513 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
514 g_sgsn[i].cfg := {
515 nsei := mp_nsconfig_sgsn[i].nsei,
516 sgsn_role := true,
517 bvc := bvcs
518 }
Harald Welte6d63f742020-11-15 19:44:04 +0100519 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200520
521 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100522 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100523 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100524 }
525 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
526 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
527 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
528 }
529
530 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100531 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100532 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200533 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100534 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100535 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100536 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100537
Harald Welteb978ed62020-12-12 14:01:11 +0100538 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
539 bvci_unblocked[i] := {};
540 }
541
Harald Weltefbae83f2020-11-15 23:25:55 +0100542 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100543 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100544 T.start;
545 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100546 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
547 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
548 [] as_count_unblocked4nse(0, bvci_unblocked);
549 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100550 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
551 repeat;
552 }
Harald Welte3c905152020-11-26 20:56:09 +0100553 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
554 repeat;
555 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100556 [] SGSN_MGMT.receive {
557 setverdict(fail, "Received unexpected message on SGSN_MGMT");
558 mtc.stop;
559 }
560
561 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
562 repeat;
563 }
564 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
565 repeat;
566 }
567 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
568 repeat;
569 }
570 [] PCU_MGMT.receive {
571 setverdict(fail, "Received unexpected message on PCU_MGMT");
572 mtc.stop;
573 }
574
575 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100576 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100577 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100578 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100579 }
580 }
581
Harald Welteb978ed62020-12-12 14:01:11 +0100582 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
583 /* iterate over list and check all BVCI */
584 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
585 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
586 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
587 setverdict(fail, "SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up");
588 mtc.stop;
589 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100590 }
591 }
Harald Welte425d3762020-12-09 14:33:18 +0100592
593 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
594 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200595}
596
597function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100598 var integer i;
599
Daniel Willmann491af2a2021-01-08 01:32:51 +0100600 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
601 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
602 * before the component is shutdown and disconnected. */
603 f_sleep(0.2);
604
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100605 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
606 f_destroy_gb(g_sgsn[i]);
607 }
608 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
609 f_destroy_gb(g_pcu[i]);
610 }
611
612 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200613}
614
615type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
616
617/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100618function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
619 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200620runs on test_CT return BSSGP_ConnHdlr {
621 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100622 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100623 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200624
625 var BSSGP_ConnHdlrPars pars := {
626 imei := f_gen_imei(imsi_suffix),
627 imsi := f_gen_imsi(imsi_suffix),
628 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100629 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200630 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100631 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200632 tlli_old := omit,
633 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100634 pcu := g_pcu,
635 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100636 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200637 t_guard := t_guard
638 };
Harald Welte207166c2021-01-16 12:52:30 +0100639 if (not have_ptmsi) {
640 pars.p_tmsi := omit;
641 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200642
643 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200644
Harald Welte25a04b12021-01-17 11:09:49 +0100645 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
646 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200647 vc_conn.start(f_handler_init(fn, id, pars));
648 return vc_conn;
649}
650
Harald Welte207166c2021-01-16 12:52:30 +0100651function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
652 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100653runs on test_CT
654{
655 var integer sgsn_idx, nri_idx;
656 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
657 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
658 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
659 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100660 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
661 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100662 /* Idea: we could also run them in parallel ? */
663 vc_conn.done;
664 }
665 }
666}
667
Harald Welte3dd21b32020-11-17 19:21:00 +0100668/* 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 +0100669private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
670runs on BSSGP_ConnHdlr {
671 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100672 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100673 /* unregister + disconnect from old BVC */
674 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100675 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100676 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
677 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
678 }
679 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100680 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100681 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
682 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
683 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
684 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100685 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100686}
687
688/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
689private 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 +0100690 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100691 /* unregister + disconnect from old BVC */
692 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100693 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100694 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
695 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
696 }
697 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100698 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100699 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
700 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
701 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
702 sgsn_ct[port_idx] := bvc_ct;
703}
704
Harald Welte425d3762020-12-09 14:33:18 +0100705private altstep as_gTguard(timer Tguard) {
706 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200707 setverdict(fail, "Tguard timeout");
708 mtc.stop;
709 }
710}
711
712/* first function called in every ConnHdlr */
713private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
714runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100715 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200716 /* do some common stuff like setting up g_pars */
717 g_pars := pars;
718
719 llc := f_llc_create(false);
720
Harald Welte3dd21b32020-11-17 19:21:00 +0100721 /* default connections on PCU side: First BVC of each NSE/PCU */
722 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100723 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100724 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100725
726 /* default connections on SGSN side: First BVC of each NSE/SGSN */
727 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
728 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100729 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200730
731 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100732 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200733
734 /* call the user-supplied test case function */
735 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100736
737 for (i := 0; i < NUM_SGSN; i := i+1) {
738 if (SGSN_PROC[i].checkstate("Connected")) {
739 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
740 }
741 }
742
743 for (i := 0; i < NUM_PCU; i := i+1) {
744 if (PCU_PROC[i].checkstate("Connected")) {
745 f_client_unregister(g_pars.imsi, PCU_PROC[i])
746 }
747 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200748}
749
Harald Welte1e834f32020-11-15 20:02:59 +0100750private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
751runs on BSSGP_ConnHdlr {
752 PT.call(BSSGP_register_client:{imsi, tlli}) {
753 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
754 }
755}
756
757private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
758runs on BSSGP_ConnHdlr {
759 PT.call(BSSGP_unregister_client:{imsi}) {
760 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
761 }
762}
763
Harald Welte22ef5d92020-11-16 13:35:14 +0100764/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
765friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100766 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
767 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100768 var PDU_BSSGP rx;
769 timer T := 1.0;
770
Daniel Willmann4798fd72020-11-24 16:23:29 +0100771 if (use_sig) {
772 PCU_SIG[pcu_idx].send(tx);
773 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100774 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100775 }
776
Harald Welte22ef5d92020-11-16 13:35:14 +0100777 T.start;
778 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100779 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
780 setverdict(pass);
781 }
Harald Welte158becf2020-12-09 12:32:32 +0100782 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100783 setverdict(pass);
784 }
Harald Welte158becf2020-12-09 12:32:32 +0100785 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100786 setverdict(fail, "Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100787 mtc.stop;
788 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100789 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Weltec5f486b2021-01-16 11:07:01 +0100790 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100791 mtc.stop;
792 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100793 [] T.timeout {
Harald Weltec5f486b2021-01-16 11:07:01 +0100794 setverdict(fail, "Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100795 mtc.stop;
796 }
797 }
798}
799
Harald Welte3148a962021-01-17 11:15:28 +0100800/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
801friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
802 integer pcu_idx := 0, boolean use_sig := false)
803runs on BSSGP_ConnHdlr return integer {
804 var integer rx_idx := -1;
805 var PDU_BSSGP rx;
806 timer T := 1.0;
807
808 if (use_sig) {
809 PCU_SIG[pcu_idx].send(tx);
810 } else {
811 PCU_PTP[pcu_idx].send(tx);
812 }
813
814 T.start;
815 alt {
816 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
817 setverdict(pass);
818 }
819 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
820 setverdict(pass);
821 }
822 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
823 setverdict(fail, "Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx);
824 mtc.stop;
825 }
826 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
827 setverdict(fail, "Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx);
828 mtc.stop;
829 }
830 [] T.timeout {
831 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
832 mtc.stop;
833 }
834 }
835 return rx_idx;
836}
837
Harald Welte22ef5d92020-11-16 13:35:14 +0100838/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
839friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100840 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
841 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100842 var PDU_BSSGP rx;
843 timer T := 1.0;
844
Daniel Willmann4798fd72020-11-24 16:23:29 +0100845 if (use_sig) {
846 SGSN_SIG[sgsn_idx].send(tx);
847 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100848 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100849 }
850
Harald Welte22ef5d92020-11-16 13:35:14 +0100851 T.start;
852 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100853 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
854 setverdict(pass);
855 }
Harald Welte158becf2020-12-09 12:32:32 +0100856 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100857 setverdict(pass);
858 }
Harald Welte158becf2020-12-09 12:32:32 +0100859 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100860 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
861 mtc.stop;
862 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100863 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
864 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
865 mtc.stop;
866 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100867 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100868 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100869 mtc.stop;
870 }
871 }
872}
Harald Welte1e834f32020-11-15 20:02:59 +0100873
Harald Welte3807ed12020-11-24 19:05:22 +0100874/***********************************************************************
875 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
876 ***********************************************************************/
877
878type component GlobalTest_CT extends test_CT {
879 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100880 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100881 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100882 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100883 port BSSGP_PT RIM_PCU[NUM_PCU];
884 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100885};
886
Harald Welte299aa482020-12-09 15:10:55 +0100887/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100888private function f_global_init() runs on GlobalTest_CT {
889 var integer i;
890 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
891 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100892 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100893 }
894 for (i := 0; i < lengthof(g_pcu); i := i+1) {
895 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100896 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100897 }
898}
899
Harald Welte299aa482020-12-09 15:10:55 +0100900/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
901private function f_global_init_ptp() runs on GlobalTest_CT {
902 var integer i;
903 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100904 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100905 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100906 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100907 }
908 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100909 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100910 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100911 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100912 }
913}
914
Harald Welte04358652021-01-17 13:48:13 +0100915/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
916private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
917{
918 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
919 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
920 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
921 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
922 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
923}
924
925/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
926private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
927{
928 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
929 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
930 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
931 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
932 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
933}
934
Harald Welte3807ed12020-11-24 19:05:22 +0100935/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
936friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
937 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100938 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100939 var PDU_BSSGP rx;
940 timer T := 1.0;
941
942 G_PCU[pcu_idx].send(tx);
943 T.start;
944 alt {
945 [] G_SGSN[sgsn_idx].receive(exp_rx) {
946 setverdict(pass);
947 }
Harald Welte04358652021-01-17 13:48:13 +0100948 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
949 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
950 }
Harald Welte3807ed12020-11-24 19:05:22 +0100951 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
952 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
953 mtc.stop;
954 }
955 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100956 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100957 mtc.stop;
958 }
959 }
960}
961
962/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
963friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
964 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100965 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100966 var PDU_BSSGP rx;
967 timer T := 1.0;
968
969 G_SGSN[sgsn_idx].send(tx);
970 T.start;
971 alt {
972 [] G_PCU[pcu_idx].receive(exp_rx) {
973 setverdict(pass);
974 }
Harald Welte04358652021-01-17 13:48:13 +0100975 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
976 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
977 }
Harald Welte3807ed12020-11-24 19:05:22 +0100978 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
979 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
980 mtc.stop;
981 }
982 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100983 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100984 mtc.stop;
985 }
986 }
987}
988
989
Daniel Willmann423d8f42020-09-08 18:58:22 +0200990/* TODO:
991 * Detach without Attach
992 * SM procedures without attach / RAU
993 * ATTACH / RAU
994 ** with / without authentication
995 ** with / without P-TMSI allocation
996 * re-transmissions of LLC frames
997 * PDP Context activation
998 ** with different GGSN config in SGSN VTY
999 ** with different PDP context type (v4/v6/v46)
1000 ** timeout from GGSN
1001 ** multiple / secondary PDP context
1002 */
1003
1004private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1005 f_sleep(5.0);
1006 setverdict(pass);
1007}
1008
1009testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001010 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001011 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001012 f_cleanup();
1013}
1014
1015friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001016 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001017 timer T := 5.0;
1018 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001019 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001020 T.start;
1021 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001022 [] 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 +02001023 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1024 }
Harald Welte16357a92020-11-17 18:20:00 +01001025 [] 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 +02001026 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
1027 mtc.stop;
1028 }
1029 [] T.timeout {
1030 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1031 mtc.stop;
1032 }
1033 }
1034 return '00'O;
1035}
1036
1037friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001038 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001039 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001040 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 +02001041 T.start;
1042 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001043 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1044 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001045 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
1046 mtc.stop;
1047 }
1048 [] T.timeout {
1049 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
1050 mtc.stop;
1051 }
1052 }
1053}
1054
1055
Harald Welte92686012020-11-15 21:45:49 +01001056/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1057private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001058 var integer ran_idx := 0;
1059 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001060 var integer i;
1061
Harald Welte0d5fceb2020-11-29 16:04:07 +01001062 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001063 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001064 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 +01001065 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001066 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 +01001067
Harald Welte0d5fceb2020-11-29 16:04:07 +01001068 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001069 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001070 }
1071 setverdict(pass);
1072}
1073
1074testcase TC_ul_unitdata() runs on test_CT
1075{
Harald Welte92686012020-11-15 21:45:49 +01001076 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001077 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001078 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001079 f_cleanup();
1080}
1081
Harald Welte78d8db92020-11-15 23:27:27 +01001082/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1083private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1084 var integer i;
1085
Harald Welte0d5fceb2020-11-29 16:04:07 +01001086 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001087 var octetstring payload := f_rnd_octstring(i);
1088 var template (value) PDU_BSSGP pdu_tx :=
1089 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1090 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1091 var template (present) PDU_BSSGP pdu_rx :=
1092 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
1093
Harald Welte0d5fceb2020-11-29 16:04:07 +01001094 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001095 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001096 }
1097 setverdict(pass);
1098}
1099
1100testcase TC_dl_unitdata() runs on test_CT
1101{
Harald Welte78d8db92020-11-15 23:27:27 +01001102 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001103 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001104 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001105 f_cleanup();
1106}
Harald Welte92686012020-11-15 21:45:49 +01001107
Harald Welte6dc2ac42020-11-16 09:16:17 +01001108private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1109 var integer i;
1110
1111 for (i := 0; i < 10; i := i+1) {
1112 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1113 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1114 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1115
Harald Welte22ef5d92020-11-16 13:35:14 +01001116 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001117 }
1118 setverdict(pass);
1119}
1120testcase TC_ra_capability() runs on test_CT
1121{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001122 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001123 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001124 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001125 f_cleanup();
1126}
1127
Daniel Willmannace3ece2020-11-16 19:53:26 +01001128private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1129 var integer i;
1130 var OCT1 tag;
1131 for (i := 0; i < 10; i := i+1) {
1132 tag := int2oct(23 + i, 1);
1133 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1134 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1135 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1136
1137 f_pcu2sgsn(pdu_tx, pdu_rx);
1138
1139 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1140 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1141 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1142
1143 f_sgsn2pcu(pdu_tx, pdu_rx);
1144 }
1145 setverdict(pass);
1146}
1147testcase TC_ra_capability_upd() runs on test_CT
1148{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001149 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001150 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001151 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001152 f_cleanup();
1153}
1154
Daniel Willmann165d6612020-11-19 14:27:29 +01001155private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1156 var integer i;
1157 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1158 for (i := 0; i < 10; i := i+1) {
1159 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1160 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1161 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1162
1163 f_pcu2sgsn(pdu_tx, pdu_rx);
1164 }
1165 setverdict(pass);
1166}
1167testcase TC_radio_status() runs on test_CT
1168{
Daniel Willmann165d6612020-11-19 14:27:29 +01001169 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001170 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001171 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001172 f_cleanup();
1173}
1174
Harald Welte3148a962021-01-17 11:15:28 +01001175private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1176 var integer i;
1177 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1178 for (i := 0; i < 10; i := i+1) {
1179 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1180 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1181 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1182 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1183 f_pcu2sgsn(pdu_tx, pdu_rx);
1184 }
1185 setverdict(pass);
1186}
1187testcase TC_radio_status_tmsi() runs on test_CT
1188{
1189 f_init();
1190 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1191 f_cleanup();
1192}
1193
1194private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1195 var integer i;
1196 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1197 for (i := 0; i < 10; i := i+1) {
1198 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1199 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1200 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1201 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1202 }
1203 setverdict(pass);
1204}
1205testcase TC_radio_status_imsi() runs on test_CT
1206{
1207 f_init();
1208 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1209 f_cleanup();
1210}
1211
1212
1213
Harald Welte99ed5072021-01-15 20:38:58 +01001214private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1215 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001216runs on GlobalTest_CT
1217{
1218 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001219 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1220 nri_bitlen := mp_nri_bitlength);
1221 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001222 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1223 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1224 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1225 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1226
1227 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1228 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1229 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1230 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1231
1232 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1233 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1234 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1235 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1236
1237 /* These messages are simple passed through so just also test sending NACK */
1238 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1239 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1240 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1241 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1242}
1243
Harald Weltec5c33732021-01-15 21:04:35 +01001244private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1245runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001246 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001247
Daniel Willmannfa67f492020-11-19 15:48:05 +01001248 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001249 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001250 }
1251 setverdict(pass);
1252}
Harald Welte3807ed12020-11-24 19:05:22 +01001253testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001254{
Harald Weltec5c33732021-01-15 21:04:35 +01001255 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001256 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001257 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001258 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1259 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1260 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1261 }
1262 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001263 f_cleanup();
1264}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001265
Harald Welte99ed5072021-01-15 20:38:58 +01001266private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1267 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001268runs on GlobalTest_CT
1269{
1270 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001271 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1272 nri_bitlen := mp_nri_bitlength);
1273 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001274 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1275 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1276 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1277 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1278
1279 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1280 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1281 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1282 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1283
1284 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1285 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1286 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1287 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1288
1289 /* These messages are simple passed through so just also test sending NACK */
1290 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1291 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1292 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1293 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1294}
1295
Harald Weltec5c33732021-01-15 21:04:35 +01001296private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1297runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001298 var integer i;
1299
Daniel Willmann087a33d2020-11-19 15:58:43 +01001300 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001301 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001302 }
1303 setverdict(pass);
1304}
Harald Welte3807ed12020-11-24 19:05:22 +01001305testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001306{
Harald Weltec5c33732021-01-15 21:04:35 +01001307 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001308 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001309 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001310 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1311 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1312 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1313 }
1314 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001315 f_cleanup();
1316}
1317
Harald Weltef8ef0282020-11-18 12:16:59 +01001318/* test the load-sharing between multiple NS-VC on the BSS side */
1319private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1320 var integer i;
1321
1322 for (i := 0; i < 10; i := i+1) {
1323 var octetstring payload := f_rnd_octstring(i);
1324 var template (value) PDU_BSSGP pdu_tx :=
1325 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001326 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001327 }
1328 setverdict(pass);
1329}
Harald Welte09a1ce42021-01-16 11:18:38 +01001330
1331private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001332{
1333 const integer num_ue := 10;
1334 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001335 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1336 * side so we get the raw NsUnitdataIndication and hence observe different
1337 * NSVCI */
1338 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1339 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1340
1341 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1342 * of the NS-VC is ALIVE/UNBLOCKED */
1343 f_sleep(3.0);
1344
1345 /* start parallel components generating DL-UNITDATA from the SGSN side */
1346 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001347 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001348 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001349 }
1350
1351 /* now start counting all the messages that were queued before */
1352 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1353 var ro_integer rx_count := { 0, 0, 0, 0 };
1354 timer T := 2.0;
1355 T.start;
1356 alt {
1357 [] as_NsUdiCount(0, rx_count);
1358 [] as_NsUdiCount(1, rx_count);
1359 [] as_NsUdiCount(2, rx_count);
1360 [] as_NsUdiCount(3, rx_count);
1361 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1362 [] NS.receive(NsStatusIndication:?) { repeat; }
1363 [] NS.receive {
1364 setverdict(fail, "Rx unexpected NS");
1365 mtc.stop;
1366 }
1367 [] T.timeout {
1368 }
1369 }
1370 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1371 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1372 if (rx_count[i] == 0) {
1373 setverdict(fail, "Data not shared over all NSVC");
1374 }
1375 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001376}
1377
1378testcase TC_load_sharing_dl() runs on test_CT_NS
1379{
1380 var integer sgsn_idx, nri_idx;
1381 f_init();
1382 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1383 f_TC_load_sharing_dl(sgsn_idx);
1384 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001385 setverdict(pass);
1386}
1387private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1388 var NsUnitdataIndication udi;
1389 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1390 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1391 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1392 repeat;
1393 }
1394}
1395type component test_CT_NS extends test_CT {
1396 port NS_PT NS;
1397};
1398
1399
Harald Welte0e188242020-11-22 21:46:48 +01001400/***********************************************************************
1401 * PAGING PS procedure
1402 ***********************************************************************/
1403
1404private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1405 boolean use_sig := false)
1406runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1407 var template (value) PDU_BSSGP pdu_tx;
1408 var template (present) PDU_BSSGP pdu_rx;
1409 /* we always specify '0' as BVCI in the templates below, as we override it with
1410 * 'p4' later anyway */
1411 pdu_rx := tr_BSSGP_PS_PAGING(0);
1412 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1413 if (ispresent(g_pars.p_tmsi)) {
1414 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1415 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1416 } else {
1417 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1418 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1419 }
1420 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1421 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1422 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001423 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001424 } else {
1425 SGSN_SIG[sgsn_idx].send(pdu_tx);
1426 }
1427 return pdu_rx;
1428}
1429
1430/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1431 * specified PCU index */
1432private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1433 boolean use_sig := false,integer pcu_idx := 0)
1434runs on BSSGP_ConnHdlr {
1435 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001436 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001437 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1438 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1439 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1440 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1441 timer T := 2.0;
1442 T.start;
1443 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001444 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001445 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001446 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001447 repeat;
1448 }
1449 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1450 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1451 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001452 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001453 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001454 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001455 repeat;
1456 }
Harald Welte158becf2020-12-09 12:32:32 +01001457 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001458 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1459 }
Harald Welte158becf2020-12-09 12:32:32 +01001460 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001461 setverdict(fail, "Paging received on unexpected BVC");
1462 }
1463 [] any from PCU_SIG.receive(exp_rx) {
1464 setverdict(fail, "Paging received on unexpected BVC");
1465 }
Harald Welte158becf2020-12-09 12:32:32 +01001466 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001467 setverdict(fail, "Different Paging than expected received PTP BVC");
1468 }
1469 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1470 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1471 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001472 [not test_done] T.timeout {
1473 setverdict(fail, "Timeout waiting for paging");
1474 }
1475 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001476 }
1477}
1478
Harald Welte7462a592020-11-23 22:07:07 +01001479/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1480private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1481 boolean use_sig := false)
1482runs on BSSGP_ConnHdlr {
1483 var template (present) PDU_BSSGP exp_rx;
1484 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1485 /* Expect paging to propagate to no BSS */
1486 timer T := 2.0;
1487 T.start;
1488 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001489 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001490 setverdict(fail, "Paging received on unexpected BVC");
1491 }
1492 [] any from PCU_SIG.receive(exp_rx) {
1493 setverdict(fail, "Paging received on unexpected BVC");
1494 }
Harald Welte158becf2020-12-09 12:32:32 +01001495 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001496 setverdict(fail, "Different Paging received on PTP BVC");
1497 }
1498 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1499 setverdict(fail, "Different Paging received on SIGNALING BVC");
1500 }
1501 [] T.timeout {
1502 setverdict(pass);
1503 }
1504 }
1505}
1506
Harald Welte0e188242020-11-22 21:46:48 +01001507private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1508{
1509 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1510 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1511 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1512}
1513testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001514 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001515 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001516 f_cleanup();
1517}
1518
1519/* PS-PAGING on PTP-BVC for Location Area */
1520private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1521{
1522 var template (present) PDU_BSSGP exp_rx;
1523 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1524 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1525 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1526}
1527testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001528 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001529 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001530 f_cleanup();
1531}
1532
Harald Welte7462a592020-11-23 22:07:07 +01001533/* PS-PAGING on PTP-BVC for unknown Location Area */
1534private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1535{
1536 var GSM_Types.LocationAreaIdentification unknown_la := {
1537 mcc_mnc := '567F99'H,
1538 lac := 33333
1539 };
1540 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1541 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1542}
1543testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001544 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001545 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001546 f_cleanup();
1547}
1548
Harald Welte0e188242020-11-22 21:46:48 +01001549/* PS-PAGING on PTP-BVC for Routeing Area */
1550private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1551{
1552 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1553 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1554 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1555}
1556testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001557 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001558 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001559 f_cleanup();
1560}
1561
Harald Welte7462a592020-11-23 22:07:07 +01001562/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1563private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1564{
1565 var RoutingAreaIdentification unknown_ra := {
1566 lai := {
1567 mcc_mnc := '567F99'H,
1568 lac := 33333
1569 },
1570 rac := 254
1571 };
1572 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1573 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1574}
1575testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001576 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001577 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001578 f_cleanup();
1579}
1580
Harald Welte0e188242020-11-22 21:46:48 +01001581/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1582private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1583{
1584 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1585 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1586}
1587testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001588 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001589 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001590 f_cleanup();
1591}
1592
Harald Welteb5a04aa2021-01-16 13:04:40 +01001593
1594/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1595testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1596 f_init();
1597 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1598 f_cleanup();
1599}
1600
Harald Weltecf200072021-01-16 15:20:46 +01001601/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1602testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1603 f_init();
1604 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1605 f_cleanup();
1606}
1607
1608/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1609private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1610{
1611 /* first send the PS-PAGING from SGSN -> PCU */
1612 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1613 /* then simulate the PS-PAGING-REJECT from the PCU */
1614 f_send_paging_ps_rej(use_sig:=false);
1615}
1616testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1617 f_init();
1618 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1619 f_cleanup();
1620}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001621
Harald Welte7462a592020-11-23 22:07:07 +01001622/* PS-PAGING on PTP-BVC for unknown BVCI */
1623private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1624{
1625 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1626 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1627}
1628testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001629 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001630 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001631 f_cleanup();
1632}
1633
Harald Welte7595d562021-01-16 19:09:20 +01001634/* DUMMY PAGING PS on PTP BVC */
1635private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1636{
1637 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1638 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1639 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1640 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1641}
1642testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1643 f_init();
1644 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1645 f_cleanup();
1646}
1647
Harald Welte0e188242020-11-22 21:46:48 +01001648/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1649private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1650runs on BSSGP_ConnHdlr {
1651[] PCU_SIG[pcu_idx].receive(exp_rx) {
1652 if (ro_integer_contains(roi, pcu_idx)) {
1653 setverdict(fail, "Received multiple paging on same SIG BVC");
1654 }
1655 roi := roi & { pcu_idx };
1656 repeat;
1657 }
Harald Welte158becf2020-12-09 12:32:32 +01001658[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001659 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1660 }
1661[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1662 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1663 }
Harald Welte158becf2020-12-09 12:32:32 +01001664[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001665 setverdict(fail, "Different Paging than expected received PTP BVC");
1666 }
1667}
1668
1669type record of default ro_default;
1670
1671/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1672private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1673 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1674{
1675 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001676 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001677
1678 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1679 var ro_default defaults := {};
1680 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1681 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1682 defaults := defaults & { d };
1683 }
1684 f_sleep(2.0);
1685 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1686 deactivate(defaults[i]);
1687 }
1688 log("Paging received on PCU ", g_roi);
1689
1690 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1691 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1692 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1693 if (exp_on_i and not rx_on_i) {
1694 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1695 }
1696 if (not exp_on_i and rx_on_i) {
1697 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1698 }
1699 }
1700 setverdict(pass);
1701}
1702
Harald Weltecf200072021-01-16 15:20:46 +01001703/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1704private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1705{
1706 var template (value) PDU_BSSGP pdu_tx;
1707 var template (present) PDU_BSSGP exp_rx;
1708 var PDU_BSSGP pdu_rx;
1709 timer T := 5.0;
1710 var template (omit) GsmTmsi tmsi_int := omit;
1711
1712 if (ispresent(g_pars.p_tmsi)) {
1713 tmsi_int := oct2int(g_pars.p_tmsi);
1714 }
1715
1716 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1717 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1718
1719 if (use_sig) {
1720 PCU_SIG[pcu_idx].send(pdu_tx);
1721 } else {
1722 PCU_PTP[pcu_idx].send(pdu_tx);
1723 }
1724 T.start;
1725 alt {
1726 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1727 setverdict(pass);
1728 }
1729 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1730 setverdict(fail, "Unexpected PDU on SGSN");
1731 }
1732 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1733 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1734 }
1735 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1736 setverdict(pass);
1737 }
1738 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1739 setverdict(fail, "Unexpected PDU on SGSN");
1740 }
1741 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1742 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1743 }
1744 [] T.timeout {
1745 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1746 }
1747 }
1748}
1749
Harald Welte0e188242020-11-22 21:46:48 +01001750/* PS-PAGING on SIG-BVC for BSS Area */
1751private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1752{
1753 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001754 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001755}
1756testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001757 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001758 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001759 f_cleanup();
1760}
1761
1762/* PS-PAGING on SIG-BVC for Location Area */
1763private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1764{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001765 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001766 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 +01001767 /* Reset state */
1768 g_roi := {};
1769 /* Make LAC (13300) available on pcu index 2 */
1770 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001771 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 +01001772}
1773testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001774 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001775 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001776 f_cleanup();
1777}
1778
Harald Welte7462a592020-11-23 22:07:07 +01001779/* PS-PAGING on SIG-BVC for unknown Location Area */
1780private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1781{
1782 var GSM_Types.LocationAreaIdentification unknown_la := {
1783 mcc_mnc := '567F99'H,
1784 lac := 33333
1785 };
1786 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1787}
1788testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001789 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001790 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001791 f_cleanup();
1792}
1793
Harald Welte0e188242020-11-22 21:46:48 +01001794/* PS-PAGING on SIG-BVC for Routeing Area */
1795private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1796{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001797 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001798 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 +01001799 g_roi := {};
1800 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001801 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 +01001802 g_roi := {};
1803 /* PCU index 2 has two matching BVCs with the RA ID */
1804 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001805 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 +01001806}
1807testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001808 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001809 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001810 f_cleanup();
1811}
1812
Harald Welte7462a592020-11-23 22:07:07 +01001813/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1814private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1815{
1816 var RoutingAreaIdentification unknown_ra := {
1817 lai := {
1818 mcc_mnc := '567F99'H,
1819 lac := 33333
1820 },
1821 rac := 254
1822 };
1823 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1824}
1825testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001826 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001827 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001828 f_cleanup();
1829}
1830
Harald Welte0e188242020-11-22 21:46:48 +01001831/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1832private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1833{
Daniel Willmann43320442021-01-17 14:07:05 +01001834 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 +01001835}
1836testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001837 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001838 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001839 f_cleanup();
1840}
1841
Harald Welteb5a04aa2021-01-16 13:04:40 +01001842/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1843testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1844 f_init();
1845 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1846 f_cleanup();
1847}
1848
Harald Weltecf200072021-01-16 15:20:46 +01001849/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1850private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1851{
1852 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001853 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 +01001854 /* then simulate the PS-PAGING-REJECT from the PCU */
1855 f_send_paging_ps_rej(use_sig:=true);
1856
1857}
1858testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1859 f_init();
1860 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1861 f_cleanup();
1862}
1863
1864/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1865testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1866 f_init();
1867 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1868 f_cleanup();
1869}
1870
Harald Welte7462a592020-11-23 22:07:07 +01001871/* PS-PAGING on SIG-BVC for unknown BVCI */
1872private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1873{
1874 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1875}
1876testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001877 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001878 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001879 f_cleanup();
1880}
1881
Harald Welte7595d562021-01-16 19:09:20 +01001882/* DUMMY PAGING PS on SIG BVC */
1883private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1884{
1885 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1886 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1887 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1888 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1889}
1890testcase TC_dummy_paging_ps_sig() runs on test_CT {
1891 f_init();
1892 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1893 f_cleanup();
1894}
1895
Harald Welte7462a592020-11-23 22:07:07 +01001896
Harald Welte0e188242020-11-22 21:46:48 +01001897
1898/***********************************************************************
1899 * PAGING CS procedure
1900 ***********************************************************************/
1901
1902private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1903 boolean use_sig := false)
1904runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1905 var template (value) PDU_BSSGP pdu_tx;
1906 var template (present) PDU_BSSGP pdu_rx;
1907 /* we always specify '0' as BVCI in the templates below, as we override it with
1908 * 'p4' later anyway */
1909 pdu_rx := tr_BSSGP_CS_PAGING(0);
1910 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1911 if (ispresent(g_pars.p_tmsi)) {
1912 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1913 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1914 } else {
1915 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1916 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1917 }
1918 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1919 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1920 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001921 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001922 } else {
1923 SGSN_SIG[sgsn_idx].send(pdu_tx);
1924 }
1925 return pdu_rx;
1926}
1927
1928/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1929 * specified PCU index */
1930private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1931 boolean use_sig := false,integer pcu_idx := 0)
1932runs on BSSGP_ConnHdlr {
1933 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001934 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001935 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1936 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1937 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1938 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1939 timer T := 2.0;
1940 T.start;
1941 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001942 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001943 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001944 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001945 repeat;
1946 }
1947 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1948 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1949 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001950 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001951 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001952 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001953 repeat;
1954 }
Harald Welte158becf2020-12-09 12:32:32 +01001955 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001956 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1957 }
Harald Welte158becf2020-12-09 12:32:32 +01001958 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001959 setverdict(fail, "Paging received on unexpected BVC");
1960 }
1961 [] any from PCU_SIG.receive(exp_rx) {
1962 setverdict(fail, "Paging received on unexpected BVC");
1963 }
Harald Welte158becf2020-12-09 12:32:32 +01001964 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001965 setverdict(fail, "Different Paging than expected received PTP BVC");
1966 }
1967 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1968 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1969 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001970 [not test_done] T.timeout {
1971 setverdict(fail, "Timeout while waiting for paging")
1972 }
1973 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001974 }
1975}
1976
Harald Welte7462a592020-11-23 22:07:07 +01001977/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1978private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1979 boolean use_sig := false)
1980runs on BSSGP_ConnHdlr {
1981 var template (present) PDU_BSSGP exp_rx;
1982 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1983 /* Expect paging to propagate to no BSS */
1984 timer T := 2.0;
1985 T.start;
1986 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001987 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001988 setverdict(fail, "Paging received on unexpected BVC");
1989 }
1990 [] any from PCU_SIG.receive(exp_rx) {
1991 setverdict(fail, "Paging received on unexpected BVC");
1992 }
Harald Welte158becf2020-12-09 12:32:32 +01001993 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001994 setverdict(fail, "Different Paging received on PTP BVC");
1995 }
1996 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1997 setverdict(fail, "Different Paging received on SIGNALING BVC");
1998 }
1999 [] T.timeout {
2000 setverdict(pass);
2001 }
2002 }
2003}
2004
Harald Welte0e188242020-11-22 21:46:48 +01002005private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2006{
2007 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2008 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2009 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2010}
2011testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002012 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002013 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002014 f_cleanup();
2015}
2016
2017/* CS-PAGING on PTP-BVC for Location Area */
2018private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2019{
2020 var template (present) PDU_BSSGP exp_rx;
2021 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2022 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2023 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2024}
2025testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002026 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002027 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002028 f_cleanup();
2029}
2030
Harald Welte7462a592020-11-23 22:07:07 +01002031/* CS-PAGING on PTP-BVC for unknown Location Area */
2032private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2033{
2034 var GSM_Types.LocationAreaIdentification unknown_la := {
2035 mcc_mnc := '567F99'H,
2036 lac := 33333
2037 };
2038 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2039 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2040}
2041testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002042 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002043 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002044 f_cleanup();
2045}
2046
Harald Welte0e188242020-11-22 21:46:48 +01002047/* CS-PAGING on PTP-BVC for Routeing Area */
2048private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2049{
2050 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2051 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2052 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2053}
2054testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002055 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002056 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002057 f_cleanup();
2058}
2059
Harald Welte7462a592020-11-23 22:07:07 +01002060/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2061private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2062{
2063 var RoutingAreaIdentification unknown_ra := {
2064 lai := {
2065 mcc_mnc := '567F99'H,
2066 lac := 33333
2067 },
2068 rac := 254
2069 };
2070 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2071 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2072}
2073testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002074 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002075 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002076 f_cleanup();
2077}
2078
Harald Welte0e188242020-11-22 21:46:48 +01002079/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2080private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2081{
2082 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2083 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2084}
2085testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002086 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002087 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002088 f_cleanup();
2089}
2090
Harald Welte7462a592020-11-23 22:07:07 +01002091/* CS-PAGING on PTP-BVC for unknown BVCI */
2092private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2093{
2094 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2095 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2096}
2097testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002098 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002099 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002100 f_cleanup();
2101}
2102
Harald Welte0e188242020-11-22 21:46:48 +01002103/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2104private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2105 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2106{
2107 var template (present) PDU_BSSGP exp_rx;
2108 exp_rx := f_send_paging_cs(p4, 0, true);
2109
2110 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2111 var ro_default defaults := {};
2112 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2113 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2114 defaults := defaults & { d };
2115 }
2116 f_sleep(2.0);
2117 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2118 deactivate(defaults[i]);
2119 }
2120 log("Paging received on PCU ", g_roi);
2121
2122 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2123 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2124 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2125 if (exp_on_i and not rx_on_i) {
2126 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2127 }
2128 if (not exp_on_i and rx_on_i) {
2129 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2130 }
2131 }
2132 setverdict(pass);
2133}
2134
2135/* CS-PAGING on SIG-BVC for BSS Area */
2136private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2137{
2138 /* we expect the paging to arrive on all three NSE */
2139 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2140}
2141testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002142 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002143 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002144 f_cleanup();
2145}
2146
2147/* CS-PAGING on SIG-BVC for Location Area */
2148private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2149{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002150 /* The first LAC (13135) is shared by all three NSEs */
2151 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2152 /* Reset state */
2153 g_roi := {};
2154 /* Make LAC (13300) available on pcu index 2 */
2155 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2156 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 +01002157}
2158testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002159 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002160 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002161 f_cleanup();
2162}
2163
Harald Welte7462a592020-11-23 22:07:07 +01002164/* CS-PAGING on SIG-BVC for unknown Location Area */
2165private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2166{
2167 var GSM_Types.LocationAreaIdentification unknown_la := {
2168 mcc_mnc := '567F99'H,
2169 lac := 33333
2170 };
2171 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2172}
2173testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002174 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002175 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002176 f_cleanup();
2177}
2178
Harald Welte0e188242020-11-22 21:46:48 +01002179/* CS-PAGING on SIG-BVC for Routeing Area */
2180private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2181{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002182 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002183 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 +01002184 g_roi := {};
2185 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2186 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2187 g_roi := {};
2188 /* PCU index 2 has two matching BVCs with the RA ID */
2189 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2190 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 +01002191}
2192testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002193 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002194 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002195 f_cleanup();
2196}
2197
Harald Welte7462a592020-11-23 22:07:07 +01002198/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2199private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2200{
2201 var RoutingAreaIdentification unknown_ra := {
2202 lai := {
2203 mcc_mnc := '567F99'H,
2204 lac := 33333
2205 },
2206 rac := 254
2207 };
2208 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2209}
2210testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002211 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002212 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002213 f_cleanup();
2214}
2215
Harald Welte0e188242020-11-22 21:46:48 +01002216/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2217private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2218{
2219 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2220}
2221testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002222 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002223 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002224 f_cleanup();
2225}
2226
Harald Welte7462a592020-11-23 22:07:07 +01002227/* CS-PAGING on SIG-BVC for unknown BVCI */
2228private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2229{
2230 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2231}
2232testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002233 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002234 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002235 f_cleanup();
2236}
2237
Harald Welte4f91c3b2020-12-09 12:25:51 +01002238/***********************************************************************
2239 * FLUSH-LL procedure
2240 ***********************************************************************/
2241
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002242private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2243 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2244 var integer i;
2245 for (i := 0; i < 10; i := i+1) {
2246 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2247 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2248 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2249
2250 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2251
2252 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2253 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2254 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2255
2256 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2257 }
2258 setverdict(pass);
2259}
2260testcase TC_flush_ll() runs on test_CT
2261{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002262 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002263 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002264 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002265 f_cleanup();
2266}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002267
Harald Welte4f91c3b2020-12-09 12:25:51 +01002268/***********************************************************************
2269 * SGSN-INVOKE-TRACE procedure
2270 ***********************************************************************/
2271
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002272private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2273runs on GlobalTest_CT {
2274[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2275 if (ro_integer_contains(roi, pcu_idx)) {
2276 setverdict(fail, "Received multiple on same SIG BVC");
2277 }
2278 roi := roi & { pcu_idx };
2279 repeat;
2280 }
2281}
2282/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2283testcase TC_trace() runs on GlobalTest_CT
2284{
2285 var BSSGP_ConnHdlr vc_conn;
2286 f_init();
2287 f_global_init();
2288
2289 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2290 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2291
2292 var ro_default defaults := {};
2293 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2294 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2295 }
2296 G_SGSN[0].send(pdu_tx);
2297 f_sleep(2.0);
2298 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2299 deactivate(defaults[i]);
2300 }
2301
2302 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2303 if (not ro_integer_contains(g_roi, i)) {
2304 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2305 }
2306 }
2307 setverdict(pass);
2308
2309 f_cleanup();
2310}
2311
Harald Welte4f91c3b2020-12-09 12:25:51 +01002312/***********************************************************************
2313 * LLC-DISCARDED procedure
2314 ***********************************************************************/
2315
Harald Weltec0351d12020-11-27 22:49:02 +01002316private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2317 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2318
2319 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2320 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2321 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2322
2323 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2324
2325 setverdict(pass);
2326}
2327/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2328testcase TC_llc_discarded() runs on test_CT
2329{
Harald Weltec0351d12020-11-27 22:49:02 +01002330 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002331 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002332 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002333 f_cleanup();
2334}
2335
Harald Welte4f91c3b2020-12-09 12:25:51 +01002336/***********************************************************************
2337 * OVERLOAD procedure
2338 ***********************************************************************/
2339
Harald Weltef20af412020-11-28 16:11:11 +01002340/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2341testcase TC_overload() runs on GlobalTest_CT
2342{
2343 f_init();
2344 f_global_init();
2345
2346 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2347 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2348
2349 var ro_default defaults := {};
2350 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2351 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2352 }
2353 G_SGSN[0].send(pdu_tx);
2354 f_sleep(2.0);
2355 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2356 deactivate(defaults[i]);
2357 }
2358
2359 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2360 if (not ro_integer_contains(g_roi, i)) {
2361 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2362 }
2363 }
2364 setverdict(pass);
2365
2366 f_cleanup();
2367}
2368
Harald Welte4f91c3b2020-12-09 12:25:51 +01002369/***********************************************************************
2370 * BVC-BLOCK / BVC-UNBLOCK procedure
2371 ***********************************************************************/
2372
Harald Welte239aa502020-11-24 23:14:20 +01002373private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2374{
2375 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2376 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2377 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2378
2379 SGSN_MGMT.clear;
2380 PCU_MGMT.clear;
2381
2382 /* block the PTP BVC from the PCU side */
2383 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2384 /* expect state on both PCU and SGSN side to change */
2385 interleave {
2386 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2387 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2388 }
2389 setverdict(pass);
2390}
2391testcase TC_bvc_block_ptp() runs on test_CT
2392{
2393 f_init();
2394 f_sleep(1.0);
2395 f_block_ptp_bvc_from_pcu(0, 0);
2396 f_cleanup();
2397}
2398
2399private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2400{
2401 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2402 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2403 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2404
2405 SGSN_MGMT.clear;
2406 PCU_MGMT.clear;
2407
2408 /* block the PTP BVC from the PCU side */
2409 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2410 /* expect state on both PCU and SGSN side to change */
2411 interleave {
2412 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2413 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2414 }
2415 setverdict(pass);
2416}
2417testcase TC_bvc_unblock_ptp() runs on test_CT
2418{
2419 f_init();
2420 f_sleep(1.0);
2421 f_block_ptp_bvc_from_pcu(0, 0);
2422 f_sleep(1.0);
2423 f_unblock_ptp_bvc_from_pcu(0, 0);
2424 f_cleanup();
2425}
2426
Harald Welte4f91c3b2020-12-09 12:25:51 +01002427/***********************************************************************
2428 * BVC-RESET procedure
2429 ***********************************************************************/
2430
Harald Welte60a8ec72020-11-25 17:12:53 +01002431private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2432[] pt.receive(BssgpStatusIndication:?) { repeat; }
2433}
2434private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2435 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2436 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2437 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2438 }
2439 }
2440 return null;
2441}
2442private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2443{
2444 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2445 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2446 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2447 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2448 var default d;
2449
2450 SGSN_MGMT.clear;
2451 PCU_MGMT.clear;
2452
2453 /* block the PTP BVC from the PCU side */
2454 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2455 /* expect state on both PCU and SGSN side to change */
2456 d := activate(as_ignore_status(SGSN_MGMT));
2457 interleave {
2458 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2459 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2460 }
2461 deactivate(d);
2462 setverdict(pass);
2463}
2464/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2465testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2466{
2467 f_init();
2468 f_sleep(3.0);
2469 f_reset_ptp_bvc_from_pcu(0, 0);
2470 f_cleanup();
2471}
2472
Harald Welte16786e92020-11-27 19:11:56 +01002473private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2474runs on test_CT {
2475 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2476 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2477 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002478 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002479 }
2480}
2481/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2482testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2483
2484 f_init();
2485 f_sleep(3.0);
2486
2487 /* Start BVC-RESET procedure for BVCI=0 */
2488 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2489
2490 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2491 var ro_default defaults := {};
2492 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2493 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2494 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2495 defaults := defaults & { d };
2496 }
2497
2498 timer T := 3.0;
2499 T.start;
2500 alt {
2501 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2502 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2503 }
2504 [] T.timeout;
2505 }
2506
2507 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2508 deactivate(defaults[i]);
2509 }
2510
2511 /* check if BVC-block was received on all expected BVC */
2512 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2513 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2514 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2515 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2516 }
2517 }
2518
2519 /* check if BVC-block was not received on any unexpected BVC is not required as
2520 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002521 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002522 f_cleanup();
2523}
2524
Harald Welte60a8ec72020-11-25 17:12:53 +01002525private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2526{
2527 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2528 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2529 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2530 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2531 var default d;
2532
2533 SGSN_MGMT.clear;
2534 PCU_MGMT.clear;
2535
2536 /* block the PTP BVC from the PCU side */
2537 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2538 /* expect state on both PCU and SGSN side to change */
2539 d := activate(as_ignore_status(PCU_MGMT));
2540 interleave {
2541 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2542 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2543 }
2544 deactivate(d);
2545 setverdict(pass);
2546}
2547/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2548testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2549{
2550 f_init();
2551 f_sleep(3.0);
2552 f_reset_ptp_bvc_from_sgsn(0, 0);
2553 f_cleanup();
2554}
2555
Daniel Willmannef7015f2021-01-08 00:43:56 +01002556private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2557 [] pt.receive {repeat; }
2558}
2559
Harald Welte16786e92020-11-27 19:11:56 +01002560private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2561runs on test_CT {
2562 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2563 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2564 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002565 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002566 }
2567}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002568
Harald Welte16786e92020-11-27 19:11:56 +01002569/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2570testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2571
2572 f_init();
2573 f_sleep(3.0);
2574
Daniel Willmannef7015f2021-01-08 00:43:56 +01002575 SGSN_MGMT.clear;
2576 PCU_MGMT.clear;
2577
Harald Welte16786e92020-11-27 19:11:56 +01002578 /* Start BVC-RESET procedure for BVCI=0 */
2579 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2580
Daniel Willmannef7015f2021-01-08 00:43:56 +01002581 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2582 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2583 * the port and a different message sits at the front we wait forever and fail the test.
2584 */
2585 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2586
Harald Welte16786e92020-11-27 19:11:56 +01002587 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002588 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2589 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2590 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2591 defaults := defaults & { d };
2592 }
2593
2594 f_sleep(3.0);
2595
2596 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2597 deactivate(defaults[i]);
2598 }
2599
2600 /* check if BVC-block was received on all expected BVC */
2601 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2602 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2603 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2604 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2605 }
2606 }
2607
2608 /* check if BVC-block was not received on any unexpected BVC is not required as
2609 * such a message would basically run into 'no matching clause' */
2610
2611 f_cleanup();
2612}
2613
Harald Welte299aa482020-12-09 15:10:55 +01002614/***********************************************************************
2615 * FLOW-CONTROL-BVC procedure
2616 ***********************************************************************/
2617
2618private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2619 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2620runs on GlobalTest_CT {
2621 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2622 roi := roi & { sgsn_idx };
2623 if (ispresent(tx_reply)) {
2624 G_SGSN[sgsn_idx].send(tx_reply);
2625 }
Harald Welte5fb01742021-01-15 21:07:52 +01002626 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002627 }
2628}
2629/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2630testcase TC_fc_bvc() runs on GlobalTest_CT
2631{
2632 f_init();
2633 f_global_init_ptp();
2634
2635 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2636 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2637 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2638 var template (omit) PDU_BSSGP ack_tx :=
2639 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2640
2641 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2642 G_PCU[0].send(pdu_tx);
2643
2644 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2645 var ro_default defaults := {};
2646 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2647 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2648 defaults := defaults & { d };
2649 }
2650
2651 f_sleep(3.0);
2652
2653 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2654 deactivate(defaults[i]);
2655 }
2656
2657 /* check if BVC-block was received on all expected BVC */
2658 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2659 if (not ro_integer_contains(g_roi, i)) {
2660 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2661 }
2662 }
2663
2664 /* Expect ACK on PCU side */
2665 G_PCU[0].receive(ack_tx);
2666
2667 setverdict(pass);
2668
2669 f_cleanup();
2670}
2671
Harald Weltecc3894b2020-12-09 16:50:12 +01002672/***********************************************************************
2673 * FLOW-CONTROL-MS procedure
2674 ***********************************************************************/
2675
2676private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2677 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2678
2679 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2680 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2681 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2682 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2683
2684 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2685 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2686
2687 setverdict(pass);
2688}
2689/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2690testcase TC_fc_ms() runs on test_CT
2691{
Harald Weltecc3894b2020-12-09 16:50:12 +01002692 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002693 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002694 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002695 f_cleanup();
2696}
2697
Harald Welted6f89812021-01-16 18:57:49 +01002698/***********************************************************************
2699 * MS-REGISTRATION ENQUIRY procedure
2700 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002701
Harald Welted6f89812021-01-16 18:57:49 +01002702private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2703{
2704 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2705 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);
2706}
2707testcase TC_ms_reg_enq() runs on test_CT
2708{
2709 f_init();
2710 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2711 f_cleanup();
2712}
Harald Welte299aa482020-12-09 15:10:55 +01002713
Harald Weltef86f1852021-01-16 21:56:17 +01002714/***********************************************************************
2715 * RIM (RAN Information Management)
2716 ***********************************************************************/
2717
2718/* Our tests here are rather synthetic, as they don't reflect normal message flows
2719 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2720 matter as gbproxy is not concerned with anything but the source / destination routing
2721 information */
2722
2723/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2724 one here of which we know it is not used among the [simulated] PCUs */
2725const BssgpCellId cell_id_sgsn := {
2726 ra_id := {
2727 lai := {
2728 mcc_mnc := c_mcc_mnc,
2729 lac := 65534
2730 },
2731 rac := 0
2732 },
2733 cell_id := 65533
2734};
2735
2736/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2737friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2738 integer pcu_idx := 0) runs on GlobalTest_CT {
2739 var PDU_BSSGP rx;
2740 timer T := 1.0;
2741
2742 RIM_PCU[pcu_idx].send(tx);
2743 T.start;
2744 alt {
2745 [] any from RIM_SGSN.receive(exp_rx) {
2746 setverdict(pass);
2747 }
2748 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2749 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2750 mtc.stop;
2751 }
2752 [] T.timeout {
2753 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2754 mtc.stop;
2755 }
2756 }
2757}
2758
2759/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2760friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2761 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2762 var PDU_BSSGP rx;
2763 timer T := 1.0;
2764
2765 RIM_SGSN[sgsn_idx].send(tx);
2766 T.start;
2767 alt {
2768 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2769 setverdict(pass);
2770 }
2771 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
2772 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
2773 mtc.stop;
2774 }
2775 [] T.timeout {
2776 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
2777 mtc.stop;
2778 }
2779 }
2780}
2781
2782/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2783friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2784 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2785 var integer rx_idx;
2786 var PDU_BSSGP rx;
2787 timer T := 1.0;
2788
2789 RIM_PCU[src_pcu_idx].send(tx);
2790 T.start;
2791 alt {
2792 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2793 setverdict(pass);
2794 }
2795 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2796 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2797 }
2798 [] any from RIM_SGSN.receive(exp_rx) {
2799 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2800 }
2801 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
2802 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
2803 mtc.stop;
2804 }
2805 [] T.timeout {
2806 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
2807 mtc.stop;
2808 }
2809 }
2810}
2811
2812
2813type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2814
2815/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2816 each SGSN */
2817private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2818{
2819 var integer sgsn_idx, pcu_idx, bvc_idx;
2820 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2821 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2822 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2823 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2824 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2825 }
2826 }
2827 }
2828}
2829
2830/* RAN-INFORMATION-REQUEST */
2831private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2832runs on GlobalTest_CT
2833{
2834 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2835 var template (value) RIM_Routing_Information ri_pcu;
2836 var template (value) RIM_Routing_Information ri_sgsn;
2837 var template (value) RAN_Information_Request_RIM_Container cont;
2838
2839 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2840 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2841 cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2842 ts_RIM_Sequence_Number(0),
2843 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2844 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2845 tr_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2846 pcu_idx);
2847 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2848 tr_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2849 sgsn_idx, pcu_idx);
2850}
2851testcase TC_rim_info_req() runs on GlobalTest_CT
2852{
2853 f_init();
2854 f_global_init();
2855 f_rim_iterator(refers(f_TC_rim_info_req));
2856 f_cleanup();
2857}
2858
2859/* RAN-INFORMATION */
2860private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2861runs on GlobalTest_CT
2862{
2863 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2864 var template (value) RIM_Routing_Information ri_pcu;
2865 var template (value) RIM_Routing_Information ri_sgsn;
2866 var template (value) RAN_Information_RIM_Container cont;
2867
2868 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2869 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2870 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2871 ts_RIM_Sequence_Number(0),
2872 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2873 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2874 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2875 pcu_idx);
2876 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2877 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2878 sgsn_idx, pcu_idx);
2879}
2880testcase TC_rim_info() runs on GlobalTest_CT
2881{
2882 f_init();
2883 f_global_init();
2884 f_rim_iterator(refers(f_TC_rim_info));
2885 f_cleanup();
2886}
2887
2888/* RAN-INFORMATION-ACK */
2889private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2890runs on GlobalTest_CT
2891{
2892 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2893 var template (value) RIM_Routing_Information ri_pcu;
2894 var template (value) RIM_Routing_Information ri_sgsn;
2895 var template (value) RAN_Information_Ack_RIM_Container cont;
2896
2897 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2898 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2899 cont := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2900 ts_RIM_Sequence_Number(0));
2901 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2902 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2903 pcu_idx);
2904 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2905 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2906 sgsn_idx, pcu_idx);
2907}
2908testcase TC_rim_info_ack() runs on GlobalTest_CT
2909{
2910 f_init();
2911 f_global_init();
2912 f_rim_iterator(refers(f_TC_rim_info_ack));
2913 f_cleanup();
2914}
2915
2916/* RAN-INFORMATION-ERROR */
2917private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2918runs on GlobalTest_CT
2919{
2920 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2921 var template (value) RIM_Routing_Information ri_pcu;
2922 var template (value) RIM_Routing_Information ri_sgsn;
2923 var template (value) RAN_Information_Error_RIM_Container cont;
2924
2925 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2926 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2927 cont := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2928 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
2929 omit, valueof(t_BVC_UNBLOCK(23)));
2930 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2931 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2932 pcu_idx);
2933 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2934 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2935 sgsn_idx, pcu_idx);
2936}
2937testcase TC_rim_info_error() runs on GlobalTest_CT
2938{
2939 f_init();
2940 f_global_init();
2941 f_rim_iterator(refers(f_TC_rim_info_error));
2942 f_cleanup();
2943}
2944
2945/* RAN-INFORMATION-APPLICATION-ERROR */
2946private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2947runs on GlobalTest_CT
2948{
2949 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2950 var template (value) RIM_Routing_Information ri_pcu;
2951 var template (value) RIM_Routing_Information ri_sgsn;
2952 var template (value) Application_Error_Container app_cont;
2953 var template (value) RAN_Information_Application_Error_RIM_Container cont;
2954
2955 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2956 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2957 app_cont := tsu_Application_Error_Container_NACC(cell_id, 23,
2958 tsu_Application_Container_IE_NACC_req(cell_id));
2959 cont := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2960 ts_RIM_Sequence_Number(0),
2961 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
2962 omit, app_cont);
2963 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2964 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
2965 pcu_idx);
2966 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2967 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
2968 sgsn_idx, pcu_idx);
2969}
2970testcase TC_rim_info_app_error() runs on GlobalTest_CT
2971{
2972 f_init();
2973 f_global_init();
2974 f_rim_iterator(refers(f_TC_rim_info_app_error));
2975 f_cleanup();
2976}
2977
2978/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
2979private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
2980 integer dst_pcu_idx, integer dst_bvc_idx)
2981runs on GlobalTest_CT
2982{
2983 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
2984 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
2985 var template (value) RIM_Routing_Information ri_pcu_src;
2986 var template (value) RIM_Routing_Information ri_pcu_dst;
2987 var template (value) RAN_Information_RIM_Container cont;
2988
2989 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
2990 dst_pcu_idx, "][", dst_bvc_idx, "]");
2991
2992 ri_pcu_src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
2993 t_RIM_Routing_Address_cid(cell_id_src));
2994 ri_pcu_dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
2995 t_RIM_Routing_Address_cid(cell_id_dst));
2996 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2997 ts_RIM_Sequence_Number(0),
2998 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2999 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3000 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3001 src_pcu_idx, dst_pcu_idx);
3002}
3003testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3004{
3005 var integer src_pcu_idx, dst_pcu_idx;
3006 var integer src_bvc_idx, dst_bvc_idx;
3007 f_init();
3008 f_global_init();
3009
3010 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3011 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3012 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3013 if (dst_pcu_idx == src_pcu_idx) {
3014 continue;
3015 }
3016
3017 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3018dst_bvc_idx := dst_bvc_idx + 1) {
3019 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3020 }
3021 }
3022 }
3023 }
3024
3025 f_cleanup();
3026}
3027
Harald Welte04358652021-01-17 13:48:13 +01003028/***********************************************************************
3029 * STATUS handling
3030 ***********************************************************************/
3031
3032/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3033
3034/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3035private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3036{
3037 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3038 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3039}
3040
3041/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3042private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3043{
3044 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3045 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3046}
3047
3048/* STATUS in uplink direction; expect routing by its NRI */
3049private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3050runs on GlobalTest_CT
3051{
3052 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3053 var template (present) PDU_BSSGP exp_rx :=
3054 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3055 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3056
3057 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3058}
3059
3060/* STATUS in uplink direction; expect routing by its NRI */
3061private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3062runs on GlobalTest_CT
3063{
3064 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3065 var template (present) PDU_BSSGP exp_rx :=
3066 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3067 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3068
3069 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3070}
3071
3072/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3073testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3074{
3075 var integer sgsn_idx, nri_idx;
3076
3077 f_init();
3078 f_global_init();
3079
3080 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3081 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3082 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3083 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3084 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3085
3086 f_TC_status_ul(0, sgsn_idx, inner);
3087 }
3088 }
3089
3090 f_cleanup();
3091}
3092
3093/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3094testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3095{
3096 var integer sgsn_idx, nri_idx;
3097
3098 f_init();
3099 f_global_init();
3100
3101 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3102 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3103 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3104 const hexstring imsi := '001010123456789'H
3105 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3106 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3107 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3108 f_TC_status_ul(0, sgsn_idx, inner);
3109 }
3110 }
3111
3112 f_cleanup();
3113}
3114
3115
3116/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3117testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3118{
3119 var integer sgsn_idx, nri_idx;
3120
3121 f_init();
3122 f_global_init_ptp();
3123
3124 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3125 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3126 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3127 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3128 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3129
3130 f_TC_status_ul(0, sgsn_idx, inner);
3131 }
3132 }
3133
3134 f_cleanup();
3135}
3136
3137/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3138testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3139{
3140 var integer sgsn_idx, nri_idx;
3141
3142 f_init();
3143 f_global_init_ptp();
3144
3145 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3146 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3147 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3148 const hexstring imsi := '001010123456789'H
3149 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3150 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3151 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3152 f_TC_status_ul(0, sgsn_idx, inner);
3153 }
3154 }
3155
3156 f_cleanup();
3157}
3158
3159/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3160testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3161{
3162 var integer sgsn_idx, pcu_idx, bvc_idx;
3163
3164 f_init();
3165 f_global_init();
3166
3167 /* test each BVC in each PCU from each SGSN */
3168 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3169 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3170 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3171 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3172 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3173 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3174 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3175 }
3176 }
3177 }
3178
3179 f_cleanup();
3180}
3181
3182/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3183testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3184{
3185 var integer sgsn_idx, pcu_idx, bvc_idx;
3186
3187 f_init();
3188 f_global_init_ptp();
3189
3190 /* test each BVC in each PCU from each SGSN */
3191 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3192 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3193 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3194 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3195 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3196 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3197
3198 /* some uplink PDU occurring on PTP-BVC */
3199 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3200 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3201 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3202 }
3203 }
3204 }
3205
3206 f_cleanup();
3207}
3208
3209/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3210/* 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 +01003211
Daniel Willmann423d8f42020-09-08 18:58:22 +02003212control {
3213 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003214 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003215 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003216 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003217 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003218 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003219 execute( TC_radio_status_tmsi() );
3220 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003221 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003222 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003223 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003224 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003225 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003226 execute( TC_bvc_block_ptp() );
3227 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003228 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003229 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003230 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003231 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003232 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003233 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3234 execute( TC_load_sharing_dl() );
3235 }
Harald Welte0e188242020-11-22 21:46:48 +01003236
3237 /* PAGING-PS over PTP BVC */
3238 execute( TC_paging_ps_ptp_bss() );
3239 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003240 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003241 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003242 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003243 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003244 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003245 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003246 execute( TC_paging_ps_reject_ptp_bvci() );
3247 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003248 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003249
3250 /* PAGING-PS over SIG BVC */
3251 execute( TC_paging_ps_sig_bss() );
3252 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003253 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003254 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003255 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003256 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003257 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003258 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003259 execute( TC_paging_ps_reject_sig_bvci() );
3260 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003261 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003262
3263 /* PAGING-CS over PTP BVC */
3264 execute( TC_paging_cs_ptp_bss() );
3265 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003266 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003267 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003268 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003269 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003270 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003271
3272 /* PAGING-CS over SIG BVC */
3273 execute( TC_paging_cs_sig_bss() );
3274 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003275 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003276 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003277 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003278 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003279 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003280
Harald Weltef86f1852021-01-16 21:56:17 +01003281 /* RAN Information Management */
3282 execute( TC_rim_info_req() );
3283 execute( TC_rim_info() );
3284 execute( TC_rim_info_ack() );
3285 execute( TC_rim_info_error() );
3286 execute( TC_rim_info_app_error() );
3287 execute( TC_rim_info_pcu2pcu() );
3288
Harald Welte0e188242020-11-22 21:46:48 +01003289
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003290 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003291 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003292 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003293 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003294
3295 /* Uplink STATUS */
3296 execute( TC_status_sig_ul_tlli() );
3297 execute( TC_status_sig_ul_tmsi() );
3298 execute( TC_status_ptp_ul_tlli() );
3299 execute( TC_status_ptp_ul_tmsi() );
3300
3301 /* Downlink STATUS */
3302 execute( TC_status_sig_dl_bvci() );
3303 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003304}
3305
3306
3307}