blob: 48795212982370f40cc0b7de183f9c8397a6d716 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
Harald Welte207166c2021-01-16 12:52:30 +01004 * (C) 2020-2021 Harald Welte <laforge@osmocom.org>
Daniel Willmann423d8f42020-09-08 18:58:22 +02005 * (C) 2020 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Author: Daniel Willmann <dwillmann@sysmocom.de>
9
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15
16import from General_Types all;
17import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010018import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020019import from GSM_Types all;
20import from Native_Functions all;
21import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
25import from SCCPasp_Types all;
26import from Osmocom_Gb_Types all;
27
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from TELNETasp_PortType all;
35import from Osmocom_VTY_Functions all;
36
37import from LLC_Types all;
38import from LLC_Templates all;
39
40import from GSM_RR_Types all;
41
Harald Welte6d63f742020-11-15 19:44:04 +010042/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
43const BcdMccMnc c_mcc_mnc := '262F42'H;
44
Harald Welte0d5fceb2020-11-29 16:04:07 +010045/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
46const integer max_fr_info_size := 1600;
47
Daniel Willmann423d8f42020-09-08 18:58:22 +020048modulepar {
Harald Welte77218d02021-01-15 19:59:15 +010049 /* NRI bit-length. 0 for no pooling */
50 integer mp_nri_bitlength := 5;
51 roro_integer mp_sgsn_nri := {
52 { 3 }, /* list of NRIs of first SGSN */
53 { 4 } /* list of NRIs of second SGSN */
54 };
Harald Weltef6e59b02020-12-08 08:29:09 +010055 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010056 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010057 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020058 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020059 nsei := 101,
60 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010061 handle_sns := false,
62 nsvc := {
63 {
64 provider := {
65 ip := {
66 address_family := AF_INET,
67 local_udp_port := 7777,
Harald Welted05a4a92021-01-18 12:03:53 +010068 local_ip := "127.0.0.10",
Harald Welte90f19742020-11-06 19:34:40 +010069 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010070 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +010071 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +010072 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010073 }
74 },
75 nsvci := 101
Harald Welte388057d2021-01-18 18:52:49 +010076 }, {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 7770,
81 local_ip := "127.0.0.10",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 data_weight := 1,
85 signalling_weight := 0
86 }
87 },
88 nsvci := 201
Harald Welte90f19742020-11-06 19:34:40 +010089 }
Harald Weltebe7afce2021-01-17 22:04:36 +010090
Harald Welte90f19742020-11-06 19:34:40 +010091 }
Harald Welteb978ed62020-12-12 14:01:11 +010092 }, {
93 nsei := 102,
94 role_sgsn := true,
95 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
101 local_udp_port := 8888,
Harald Welted05a4a92021-01-18 12:03:53 +0100102 local_ip := "127.0.0.11",
Harald Welteb978ed62020-12-12 14:01:11 +0100103 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100104 remote_ip := "127.0.0.1",
Harald Welte388057d2021-01-18 18:52:49 +0100105 data_weight := 0,
Harald Weltebe7afce2021-01-17 22:04:36 +0100106 signalling_weight := 1
Harald Welteb978ed62020-12-12 14:01:11 +0100107 }
108 },
109 nsvci := 102
Harald Welte388057d2021-01-18 18:52:49 +0100110 }, {
111 provider := {
112 ip := {
113 address_family := AF_INET,
114 local_udp_port := 8880,
115 local_ip := "127.0.0.11",
116 remote_udp_port := 23000,
117 remote_ip := "127.0.0.1",
118 data_weight := 1,
119 signalling_weight := 0
120 }
121 },
122 nsvci := 202
Harald Welteb978ed62020-12-12 14:01:11 +0100123 }
124 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200125 }
126 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100127 /* BSS NSEI start at 2000 + x
128 * NSVCI start from value of NSEI + 100
129 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +0100130 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200131 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100132 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200133 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100134 handle_sns := false,
135 nsvc := {
136 {
137 provider := {
138 ip := {
139 address_family := AF_INET,
140 local_udp_port := 21010,
Harald Welted05a4a92021-01-18 12:03:53 +0100141 local_ip := "127.0.1.1",
Harald Welte90f19742020-11-06 19:34:40 +0100142 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100143 remote_ip := "127.0.0.1",
144 data_weight := 1,
145 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100146 }
147 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100148 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +0100149 }
150 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200151 },
152 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100153 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200154 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100155 handle_sns := false,
156 nsvc := {
157 {
158 provider := {
159 ip := {
160 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100161 local_udp_port := 21020,
Harald Welted05a4a92021-01-18 12:03:53 +0100162 local_ip := "127.0.2.1",
Harald Welte90f19742020-11-06 19:34:40 +0100163 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100164 remote_ip := "127.0.0.1",
165 data_weight := 1,
166 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100167 }
168 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100169 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100170 }
171 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200172 },
173 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100174 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200175 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100176 handle_sns := false,
177 nsvc := {
178 {
179 provider := {
180 ip := {
181 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100182 local_udp_port := 21030,
Harald Welted05a4a92021-01-18 12:03:53 +0100183 local_ip := "127.0.3.1",
Harald Welte90f19742020-11-06 19:34:40 +0100184 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100185 remote_ip := "127.0.0.1",
186 data_weight := 1,
187 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100188 }
189 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100190 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100191 }
192 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200193 }
194 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100195 /* BVCI are NSEI*10 + x
196 * The first NSE only has one BVC, the second one 2 and so on
197 * The Cell ID is BVCI + 10000
198 * LAC/RAC are configured in such a way that:
199 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
200 * LAC 13300 is present twice in NSE(2003)
201 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
202 * RAI 13300-0 is present twice in NSE(2003)
203 */
Harald Welte6d63f742020-11-15 19:44:04 +0100204 BssgpConfigs mp_gbconfigs := {
205 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100206 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100207 sgsn_role := false,
208 bvc := {
209 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100210 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100211 cell_id := {
212 ra_id := {
213 lai := {
214 mcc_mnc := c_mcc_mnc,
215 lac := 13135
216 },
217 rac := 0
218 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100219 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100220 },
221 depth := BSSGP_DECODE_DEPTH_BSSGP,
222 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
223 }
224 }
225 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100226 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100227 sgsn_role := false,
228 bvc := {
229 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100230 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100231 cell_id := {
232 ra_id := {
233 lai := {
234 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100235 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100236 },
Harald Welte0e188242020-11-22 21:46:48 +0100237 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100238 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100239 cell_id := 30021
240 },
241 depth := BSSGP_DECODE_DEPTH_BSSGP,
242 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
243 },
244 {
245 bvci := 20022,
246 cell_id := {
247 ra_id := {
248 lai := {
249 mcc_mnc := c_mcc_mnc,
250 lac := 13135
251 },
252 rac := 2
253 },
254 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100255 },
256 depth := BSSGP_DECODE_DEPTH_BSSGP,
257 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
258 }
259 }
260 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100261 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100262 sgsn_role := false,
263 bvc := {
264 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100265 bvci := 20031,
266 cell_id := {
267 ra_id := {
268 lai := {
269 mcc_mnc := c_mcc_mnc,
270 lac := 13135
271 },
272 rac := 1
273 },
274 cell_id := 30031
275 },
276 depth := BSSGP_DECODE_DEPTH_BSSGP,
277 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
278 },
279 {
280 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100281 cell_id := {
282 ra_id := {
283 lai := {
284 mcc_mnc := c_mcc_mnc,
285 lac := 13300
286 },
287 rac := 0
288 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100289 cell_id := 30032
290 },
291 depth := BSSGP_DECODE_DEPTH_BSSGP,
292 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
293 },
294 {
295 bvci := 20033,
296 cell_id := {
297 ra_id := {
298 lai := {
299 mcc_mnc := c_mcc_mnc,
300 lac := 13300
301 },
302 rac := 0
303 },
304 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100305 },
306 depth := BSSGP_DECODE_DEPTH_BSSGP,
307 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
308 }
309 }
310 }
311 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200312};
313
Daniel Willmann423d8f42020-09-08 18:58:22 +0200314type record GbInstance {
315 NS_CT vc_NS,
316 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100317 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200318 BssgpConfig cfg
319};
Harald Welte67dc8c22020-11-17 18:32:29 +0100320type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200321
322const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100323type record of GbInstance GbInstances;
324type record of BssgpConfig BssgpConfigs;
325type record of NSConfiguration NSConfigurations;
326type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200327
Harald Welteb978ed62020-12-12 14:01:11 +0100328const integer NUM_SGSN := 2;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200329
330type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100331 var GbInstances g_pcu;
332 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200333
334 port BSSGP_CT_PROC_PT PROC;
335
Harald Weltefbae83f2020-11-15 23:25:55 +0100336 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
337 port BSSGP_BVC_MGMT_PT PCU_MGMT;
338
Daniel Willmann423d8f42020-09-08 18:58:22 +0200339 port TELNETasp_PT GBPVTY;
340
341 var boolean g_initialized := false;
342 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100343
344 var ro_integer g_roi := {};
Daniel Willmannc38c85d2021-01-21 18:11:12 +0100345 var roro_integer g_roroi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100346 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200347};
348
349type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100350 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100351 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200352 port BSSGP_PT PCU_SIG[NUM_PCU];
353 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100354 /* component reference to the component to which we're currently connected */
355 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100356 /* BSSGP BVC configuration of the component to which we're currently connected */
357 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100358
359 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100360 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200361 port BSSGP_PT SGSN_SIG[NUM_SGSN];
362 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100363 /* component reference to the component to which we're currently connected */
364 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200365
366 var BSSGP_ConnHdlrPars g_pars;
367 timer g_Tguard;
368 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100369
370 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200371}
372
373type record SGSN_ConnHdlrNetworkPars {
374 boolean expect_ptmsi,
375 boolean expect_auth,
376 boolean expect_ciph
377};
378
379type record BSSGP_ConnHdlrPars {
380 /* IMEI of the simulated ME */
381 hexstring imei,
382 /* IMSI of the simulated MS */
383 hexstring imsi,
384 /* MSISDN of the simulated MS (probably unused) */
385 hexstring msisdn,
386 /* P-TMSI allocated to the simulated MS */
387 OCT4 p_tmsi optional,
388 OCT3 p_tmsi_sig optional,
389 /* TLLI of the simulated MS */
390 OCT4 tlli,
391 OCT4 tlli_old optional,
392 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100393 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100394 GbInstances sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100395 /* The SGSN index to be used within the test */
396 integer sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397 float t_guard
398};
399
Harald Welte04358652021-01-17 13:48:13 +0100400private function get_bvc_idx_for_bvci(GbInstance gbi, BssgpBvci bvci) return integer
401{
402 var integer i;
403
404 for (i := 0; i < lengthof(gbi.cfg.bvc); i := i + 1) {
405 if (gbi.cfg.bvc[i].bvci == bvci) {
406 return i;
407 }
408 }
409 setverdict(fail, "Could not find BVC Index for BVCI ", bvci);
410 return -1;
411}
412
Daniel Willmann423d8f42020-09-08 18:58:22 +0200413private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
414 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
415 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
416
417 var RoutingAreaIdentificationV ret := {
418 mccDigit1 := mcc_mnc[0],
419 mccDigit2 := mcc_mnc[1],
420 mccDigit3 := mcc_mnc[2],
421 mncDigit3 := mcc_mnc[3],
422 mncDigit1 := mcc_mnc[4],
423 mncDigit2 := mcc_mnc[5],
424 lac := int2oct(cell_id.ra_id.lai.lac, 16),
425 rac := int2oct(cell_id.ra_id.rac, 8)
426 }
427 return ret;
428};
429
Harald Welte95339432020-12-02 18:50:52 +0100430private function f_fix_create_cb(inout BssgpConfig cfg)
431{
432 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
433 if (not isbound(cfg.bvc[i].create_cb)) {
434 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
435 }
436 }
437}
438
Daniel Willmann423d8f42020-09-08 18:58:22 +0200439private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100440 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
441 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
442 gb.vc_NS := NS_CT.create(ns_id);
443 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200444 /* connect lower end of BSSGP emulation with NS upper port */
445 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
446
Harald Welteb419d0e2020-11-16 16:45:05 +0100447 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
448 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200449
450 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100451 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 connect(self:PROC, gb.vc_BSSGP:PROC);
453 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
454 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100455 /* connect all of the per-BVC MGMT ports to our PCU_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100456 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200457 }
Harald Welteb978ed62020-12-12 14:01:11 +0100458 /* connect all of the BSSGP/NSE global MGMT port to our PCU_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100459 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460}
461
462private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100463 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
464 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
465 gb.vc_NS := NS_CT.create(ns_id);
466 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200467 /* connect lower end of BSSGP emulation with NS upper port */
468 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
469
Harald Welteb419d0e2020-11-16 16:45:05 +0100470 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
471 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200472
473 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
Harald Welteb978ed62020-12-12 14:01:11 +0100474 /* obtain the component reference of the BSSGP_BVC_CT for each PTP BVC */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200475 connect(self:PROC, gb.vc_BSSGP:PROC);
476 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
477 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Welteb978ed62020-12-12 14:01:11 +0100478 /* connect all of the per-BVC MGMT ports to our SGSN_MGMT port (1:N) */
Harald Weltefbae83f2020-11-15 23:25:55 +0100479 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200480 }
Harald Welteb978ed62020-12-12 14:01:11 +0100481 /* connect all of the BSSGP/NSE global MGMT port to our SGSN_MGMT port (1:N) */
Harald Welte16786e92020-11-27 19:11:56 +0100482 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200483}
484
485
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100486private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
487 gb.vc_NS.stop;
488 gb.vc_BSSGP.stop;
489
490 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
491 gb.vc_BSSGP_BVC[i].stop;
492 }
493}
494
Daniel Willmann423d8f42020-09-08 18:58:22 +0200495private function f_init_vty() runs on test_CT {
496 map(self:GBPVTY, system:GBPVTY);
497 f_vty_set_prompts(GBPVTY);
498 f_vty_transceive(GBPVTY, "enable");
499}
500
Harald Weltefbae83f2020-11-15 23:25:55 +0100501type record of integer ro_integer;
502
503private function ro_integer_contains(ro_integer r, integer x) return boolean {
504 for (var integer j := 0; j < lengthof(r); j := j+1) {
505 if (r[j] == x) {
506 return true;
507 }
508 }
509 return false;
510}
511
Harald Welteb978ed62020-12-12 14:01:11 +0100512private type record of ro_integer roro_integer;
513
514/* count the number of unblocked BVCI for each SGSN NSE */
515private altstep as_count_unblocked4nse(integer sgsn_idx, inout roro_integer bvci_unblocked)
516runs on test_CT {
517 var BssgpStatusIndication bsi;
518 [] SGSN_MGMT.receive(BssgpStatusIndication:{g_sgsn[sgsn_idx].cfg.nsei, ?, BVC_S_UNBLOCKED}) -> value bsi {
519 bvci_unblocked[sgsn_idx] := bvci_unblocked[sgsn_idx] & { bsi.bvci };
520 /* 'repeat' until sufficient number of BVC-rest has been received on all SGSNs */
521 for (var integer i := 0; i < lengthof(bvci_unblocked); i := i+1) {
522 if (lengthof(bvci_unblocked[i]) < lengthof(g_sgsn[i].cfg.bvc)) {
523 repeat;
524 }
525 }
526 }
527}
528
Harald Welte425d3762020-12-09 14:33:18 +0100529function f_init(float t_guard := 30.0) runs on test_CT {
Harald Welteb978ed62020-12-12 14:01:11 +0100530 var roro_integer bvci_unblocked;
Harald Weltefbae83f2020-11-15 23:25:55 +0100531 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200532 var integer i;
533
534 if (g_initialized == true) {
535 return;
536 }
537 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200538
Harald Welte425d3762020-12-09 14:33:18 +0100539 g_Tguard.start(t_guard);
540 activate(as_gTguard(g_Tguard));
541
Harald Welteb978ed62020-12-12 14:01:11 +0100542 var BssgpBvcConfigs bvcs := { };
Harald Welte6d63f742020-11-15 19:44:04 +0100543 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
544 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100545 /* make sure all have a proper crate_cb, which cannot be specified in config file */
546 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100547 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welteb978ed62020-12-12 14:01:11 +0100548 bvcs := bvcs & g_pcu[i].cfg.bvc;
549 }
550
551 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
552 g_sgsn[i].cfg := {
553 nsei := mp_nsconfig_sgsn[i].nsei,
554 sgsn_role := true,
555 bvc := bvcs
556 }
Harald Welte6d63f742020-11-15 19:44:04 +0100557 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200558
559 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100560 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100561 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100562 }
563 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
564 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
565 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
566 }
567
568 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100569 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100570 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200571 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100572 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100573 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100574 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100575
Harald Welteb978ed62020-12-12 14:01:11 +0100576 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
577 bvci_unblocked[i] := {};
578 }
579
Harald Weltefbae83f2020-11-15 23:25:55 +0100580 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100581 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100582 T.start;
583 alt {
Harald Welteb978ed62020-12-12 14:01:11 +0100584 /* TODO: We need to add more lines if NUM_SGSN increases. Activating default altsteps
585 * unfortunately doesn't work as we want to access the local variable bvci_unblocked. */
586 [] as_count_unblocked4nse(0, bvci_unblocked);
587 [lengthof(g_sgsn) > 1] as_count_unblocked4nse(1, bvci_unblocked);
Harald Weltefbae83f2020-11-15 23:25:55 +0100588 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
589 repeat;
590 }
Harald Welte3c905152020-11-26 20:56:09 +0100591 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
592 repeat;
593 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100594 [] SGSN_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100595 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on SGSN_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100596 }
597
598 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
599 repeat;
600 }
601 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
602 repeat;
603 }
604 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
605 repeat;
606 }
607 [] PCU_MGMT.receive {
Harald Welted5b7e742021-01-27 10:50:24 +0100608 f_shutdown(__FILE__, __LINE__, fail, "Received unexpected message on PCU_MGMT");
Harald Weltefbae83f2020-11-15 23:25:55 +0100609 }
610
611 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100612 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
Harald Welteb978ed62020-12-12 14:01:11 +0100613 "unblocked so far: ", bvci_unblocked);
Harald Welte6929e322020-12-12 13:10:45 +0100614 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100615 }
616 }
617
Harald Welteb978ed62020-12-12 14:01:11 +0100618 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
619 /* iterate over list and check all BVCI */
620 for (var integer j := 0; j < lengthof(g_sgsn[i].cfg.bvc); j := j+1) {
621 var BssgpBvci bvci := g_sgsn[i].cfg.bvc[j].bvci;
622 if (not ro_integer_contains(bvci_unblocked[i], bvci)) {
Harald Welted5b7e742021-01-27 10:50:24 +0100623 f_shutdown(__FILE__, __LINE__, fail,
624 log2str("SGSN ", i, " BVCI=", bvci, " was not unblocked during start-up"));
Harald Welteb978ed62020-12-12 14:01:11 +0100625 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100626 }
627 }
Harald Welte425d3762020-12-09 14:33:18 +0100628
629 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
630 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200631}
632
633function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100634 var integer i;
635
Daniel Willmann491af2a2021-01-08 01:32:51 +0100636 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
637 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
638 * before the component is shutdown and disconnected. */
639 f_sleep(0.2);
640
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100641 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
642 f_destroy_gb(g_sgsn[i]);
643 }
644 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
645 f_destroy_gb(g_pcu[i]);
646 }
647
648 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200649}
650
651type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
652
653/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte207166c2021-01-16 12:52:30 +0100654function f_start_handler(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
655 integer sgsn_idx := 0, integer nri_idx := 0, boolean have_ptmsi := true)
Daniel Willmann423d8f42020-09-08 18:58:22 +0200656runs on test_CT return BSSGP_ConnHdlr {
657 var BSSGP_ConnHdlr vc_conn;
Harald Weltec5f486b2021-01-16 11:07:01 +0100658 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
Harald Welte77218d02021-01-15 19:59:15 +0100659 var OCT4 p_tmsi := f_gen_tmsi(imsi_suffix, nri_v := nri, nri_bitlen := mp_nri_bitlength);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200660
661 var BSSGP_ConnHdlrPars pars := {
662 imei := f_gen_imei(imsi_suffix),
663 imsi := f_gen_imsi(imsi_suffix),
664 msisdn := f_gen_msisdn(imsi_suffix),
Harald Weltedbd5e672021-01-14 21:03:14 +0100665 p_tmsi := p_tmsi,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200666 p_tmsi_sig := omit,
Harald Weltedbd5e672021-01-14 21:03:14 +0100667 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL),
Daniel Willmann423d8f42020-09-08 18:58:22 +0200668 tlli_old := omit,
669 ra := omit,
Harald Welte2ecbca82021-01-16 11:23:09 +0100670 pcu := g_pcu,
671 sgsn := g_sgsn,
Harald Weltec5f486b2021-01-16 11:07:01 +0100672 sgsn_idx := sgsn_idx,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200673 t_guard := t_guard
674 };
Harald Welte207166c2021-01-16 12:52:30 +0100675 if (not have_ptmsi) {
676 pars.p_tmsi := omit;
677 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200678
679 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200680
Harald Welte25a04b12021-01-17 11:09:49 +0100681 log("Starting ", id, " for SGSN[", sgsn_idx, "], NRI=", nri, ", P-TMSI=", pars.p_tmsi,
682 ", TLLI=", pars.tlli, ", IMSI=", pars.imsi, " on component=", vc_conn);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200683 vc_conn.start(f_handler_init(fn, id, pars));
684 return vc_conn;
685}
686
Harald Welte207166c2021-01-16 12:52:30 +0100687function f_start_handlers(void_fn fn, charstring id, integer imsi_suffix, float t_guard := 30.0,
688 boolean have_ptmsi := true)
Harald Weltec5f486b2021-01-16 11:07:01 +0100689runs on test_CT
690{
691 var integer sgsn_idx, nri_idx;
692 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
693 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx:=nri_idx+1) {
694 var integer extd_imsi_suffix := 1000*sgsn_idx + 100*nri_idx;
695 var BSSGP_ConnHdlr vc_conn;
Harald Welte207166c2021-01-16 12:52:30 +0100696 vc_conn := f_start_handler(fn, id, extd_imsi_suffix, t_guard, sgsn_idx, nri_idx,
697 have_ptmsi);
Harald Weltec5f486b2021-01-16 11:07:01 +0100698 /* Idea: we could also run them in parallel ? */
699 vc_conn.done;
700 }
701 }
702}
703
Harald Welte3dd21b32020-11-17 19:21:00 +0100704/* 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 +0100705private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
706runs on BSSGP_ConnHdlr {
707 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100708 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100709 /* unregister + disconnect from old BVC */
710 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100711 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100712 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
713 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
714 }
715 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100716 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100717 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
718 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
719 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
720 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100721 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100722}
723
724/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
725private 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 +0100726 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100727 /* unregister + disconnect from old BVC */
728 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100729 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100730 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
731 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
732 }
733 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100734 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100735 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
736 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
737 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
738 sgsn_ct[port_idx] := bvc_ct;
739}
740
Harald Welte425d3762020-12-09 14:33:18 +0100741private altstep as_gTguard(timer Tguard) {
742 [] Tguard.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100743 f_shutdown(__FILE__, __LINE__, fail, "Tguard timeout");
Daniel Willmann423d8f42020-09-08 18:58:22 +0200744 }
745}
746
747/* first function called in every ConnHdlr */
748private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
749runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100750 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200751 /* do some common stuff like setting up g_pars */
752 g_pars := pars;
753
754 llc := f_llc_create(false);
755
Harald Welte3dd21b32020-11-17 19:21:00 +0100756 /* default connections on PCU side: First BVC of each NSE/PCU */
757 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100758 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100759 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100760
761 /* default connections on SGSN side: First BVC of each NSE/SGSN */
762 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
763 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100764 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200765
766 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100767 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200768
769 /* call the user-supplied test case function */
770 fn.apply(id);
Harald Welteb33fb592021-01-16 12:50:56 +0100771
772 for (i := 0; i < NUM_SGSN; i := i+1) {
773 if (SGSN_PROC[i].checkstate("Connected")) {
774 f_client_unregister(g_pars.imsi, SGSN_PROC[i])
775 }
776 }
777
778 for (i := 0; i < NUM_PCU; i := i+1) {
779 if (PCU_PROC[i].checkstate("Connected")) {
780 f_client_unregister(g_pars.imsi, PCU_PROC[i])
781 }
782 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200783}
784
Harald Welte1e834f32020-11-15 20:02:59 +0100785private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
786runs on BSSGP_ConnHdlr {
787 PT.call(BSSGP_register_client:{imsi, tlli}) {
788 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
789 }
790}
791
792private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
793runs on BSSGP_ConnHdlr {
794 PT.call(BSSGP_unregister_client:{imsi}) {
795 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
796 }
797}
798
Harald Welte22ef5d92020-11-16 13:35:14 +0100799/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
800friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100801 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
802 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100803 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100804 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100805
Daniel Willmann4798fd72020-11-24 16:23:29 +0100806 if (use_sig) {
807 PCU_SIG[pcu_idx].send(tx);
808 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100809 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100810 }
811
Harald Welte22ef5d92020-11-16 13:35:14 +0100812 T.start;
813 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100814 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
815 setverdict(pass);
816 }
Harald Welte158becf2020-12-09 12:32:32 +0100817 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100818 setverdict(pass);
819 }
Harald Welte158becf2020-12-09 12:32:32 +0100820 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100821 f_shutdown(__FILE__, __LINE__, fail,
822 log2str("Unexpected BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100823 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100824 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100825 f_shutdown(__FILE__, __LINE__, fail,
826 log2str("Unexpected SIG BSSGP on SGSN[", sgsn_idx, "] side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100827 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100828 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100829 f_shutdown(__FILE__, __LINE__, fail,
830 log2str("Timeout waiting for BSSGP on SGSN[", sgsn_idx, "] side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100831 }
832 }
833}
834
Harald Welte3148a962021-01-17 11:15:28 +0100835/* Send 'tx' from PCU; expect 'exp_rx' on _any_ SGSN */
836friend function f_pcu2any_sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
837 integer pcu_idx := 0, boolean use_sig := false)
838runs on BSSGP_ConnHdlr return integer {
839 var integer rx_idx := -1;
840 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100841 timer T := 2.0;
Harald Welte3148a962021-01-17 11:15:28 +0100842
843 if (use_sig) {
844 PCU_SIG[pcu_idx].send(tx);
845 } else {
846 PCU_PTP[pcu_idx].send(tx);
847 }
848
849 T.start;
850 alt {
851 [use_sig] any from SGSN_SIG.receive(exp_rx) -> @index value rx_idx {
852 setverdict(pass);
853 }
854 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> @index value rx_idx {
855 setverdict(pass);
856 }
857 [] any from SGSN_PTP.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100858 f_shutdown(__FILE__, __LINE__, fail,
859 log2str("Unexpected BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100860 }
861 [] any from SGSN_SIG.receive(PDU_BSSGP:?) -> value rx @index value rx_idx {
Harald Welted5b7e742021-01-27 10:50:24 +0100862 f_shutdown(__FILE__, __LINE__, fail,
863 log2str("Unexpected SIG BSSGP on SGSN[", rx_idx, "] side: ", rx));
Harald Welte3148a962021-01-17 11:15:28 +0100864 }
865 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100866 f_shutdown(__FILE__, __LINE__, fail,
867 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3148a962021-01-17 11:15:28 +0100868 }
869 }
870 return rx_idx;
871}
872
Harald Welte22ef5d92020-11-16 13:35:14 +0100873/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
874friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Harald Weltec5f486b2021-01-16 11:07:01 +0100875 integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
876 var integer sgsn_idx := g_pars.sgsn_idx;
Harald Welte22ef5d92020-11-16 13:35:14 +0100877 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100878 timer T := 2.0;
Harald Welte22ef5d92020-11-16 13:35:14 +0100879
Daniel Willmann4798fd72020-11-24 16:23:29 +0100880 if (use_sig) {
881 SGSN_SIG[sgsn_idx].send(tx);
882 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100883 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100884 }
885
Harald Welte22ef5d92020-11-16 13:35:14 +0100886 T.start;
887 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100888 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
889 setverdict(pass);
890 }
Harald Welte158becf2020-12-09 12:32:32 +0100891 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100892 setverdict(pass);
893 }
Harald Welte158becf2020-12-09 12:32:32 +0100894 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100895 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100896 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100897 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100898 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected SIG BSSGP on PCU side: ", rx));
Daniel Willmann4798fd72020-11-24 16:23:29 +0100899 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100900 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100901 f_shutdown(__FILE__, __LINE__, fail,
902 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte22ef5d92020-11-16 13:35:14 +0100903 }
904 }
905}
Harald Welte1e834f32020-11-15 20:02:59 +0100906
Harald Welte3807ed12020-11-24 19:05:22 +0100907/***********************************************************************
908 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
909 ***********************************************************************/
910
911type component GlobalTest_CT extends test_CT {
912 port BSSGP_PT G_PCU[NUM_PCU];
Harald Welte04358652021-01-17 13:48:13 +0100913 var integer g_pcu_idx[NUM_PCU]; /* BVC index currently connected to G_PCU */
Harald Welte3807ed12020-11-24 19:05:22 +0100914 port BSSGP_PT G_SGSN[NUM_SGSN];
Harald Welte04358652021-01-17 13:48:13 +0100915 var integer g_sgsn_idx[NUM_SGSN]; /* BVC index currently connected to G_SGSN */
Harald Weltef86f1852021-01-16 21:56:17 +0100916 port BSSGP_PT RIM_PCU[NUM_PCU];
917 port BSSGP_PT RIM_SGSN[NUM_SGSN];
Harald Welte3807ed12020-11-24 19:05:22 +0100918};
919
Harald Welte299aa482020-12-09 15:10:55 +0100920/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100921private function f_global_init() runs on GlobalTest_CT {
922 var integer i;
923 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
924 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100925 connect(self:RIM_SGSN[i], g_sgsn[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100926 }
927 for (i := 0; i < lengthof(g_pcu); i := i+1) {
928 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
Harald Weltef86f1852021-01-16 21:56:17 +0100929 connect(self:RIM_PCU[i], g_pcu[i].vc_BSSGP:RIM);
Harald Welte3807ed12020-11-24 19:05:22 +0100930 }
931}
932
Harald Welte299aa482020-12-09 15:10:55 +0100933/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
934private function f_global_init_ptp() runs on GlobalTest_CT {
935 var integer i;
936 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100937 log("Connecting G_SGSN[", i, "] to BVCI=", g_sgsn[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100938 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100939 g_sgsn_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100940 }
941 for (i := 0; i < lengthof(g_pcu); i := i+1) {
Harald Welte04358652021-01-17 13:48:13 +0100942 log("Connecting G_PCU[", i, "] to BVCI=", g_pcu[i].cfg.bvc[0].bvci);
Harald Welte299aa482020-12-09 15:10:55 +0100943 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
Harald Welte04358652021-01-17 13:48:13 +0100944 g_pcu_idx[i] := 0;
Harald Welte299aa482020-12-09 15:10:55 +0100945 }
946}
947
Harald Welte04358652021-01-17 13:48:13 +0100948/* (re)connect G_SGSN[sgsn_idx] to a specific PTP BVCI */
949private function f_global_ptp_connect_sgsn_bvci(integer sgsn_idx, BssgpBvci bvci) runs on GlobalTest_CT
950{
951 var integer sgsn_bvc_idx := get_bvc_idx_for_bvci(g_sgsn[sgsn_idx], bvci);
952 var integer old_sgsn_bvc_idx := g_sgsn_idx[sgsn_idx];
953 disconnect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[old_sgsn_bvc_idx]:GLOBAL);
954 connect(self:G_SGSN[sgsn_idx], g_sgsn[sgsn_idx].vc_BSSGP_BVC[sgsn_bvc_idx]:GLOBAL);
955 g_sgsn_idx[sgsn_idx] := sgsn_bvc_idx;
956}
957
958/* (re)connect G_PCU[pcu_idx] to a specific PTP BVCI */
959private function f_global_ptp_connect_pcu_bvci(integer pcu_idx, BssgpBvci bvci) runs on GlobalTest_CT
960{
961 var integer pcu_bvc_idx := get_bvc_idx_for_bvci(g_pcu[pcu_idx], bvci);
962 var integer old_pcu_bvc_idx := g_pcu_idx[pcu_idx];
963 disconnect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[old_pcu_bvc_idx]:GLOBAL);
964 connect(self:G_PCU[pcu_idx], g_pcu[pcu_idx].vc_BSSGP_BVC[pcu_bvc_idx]:GLOBAL);
965 g_pcu_idx[pcu_idx] := pcu_bvc_idx;
966}
967
Harald Welte3807ed12020-11-24 19:05:22 +0100968/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
969friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
970 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100971 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100972 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100973 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100974
975 G_PCU[pcu_idx].send(tx);
976 T.start;
977 alt {
978 [] G_SGSN[sgsn_idx].receive(exp_rx) {
979 setverdict(pass);
980 }
Harald Welte04358652021-01-17 13:48:13 +0100981 [] any from G_SGSN.receive(exp_rx) -> @index value rx_idx {
982 setverdict(fail, "BSSGP arrived on wrong SGSN[", rx_idx, "] instead of SGSN[", sgsn_idx, "]");
983 }
Harald Welte3807ed12020-11-24 19:05:22 +0100984 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +0100985 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100986 }
987 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +0100988 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +0100989 }
990 }
991}
992
993/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
994friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
995 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
Harald Welte04358652021-01-17 13:48:13 +0100996 var integer rx_idx;
Harald Welte3807ed12020-11-24 19:05:22 +0100997 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +0100998 timer T := 2.0;
Harald Welte3807ed12020-11-24 19:05:22 +0100999
1000 G_SGSN[sgsn_idx].send(tx);
1001 T.start;
1002 alt {
1003 [] G_PCU[pcu_idx].receive(exp_rx) {
1004 setverdict(pass);
1005 }
Harald Welte04358652021-01-17 13:48:13 +01001006 [] any from G_PCU.receive(exp_rx) -> @index value rx_idx {
1007 setverdict(fail, "BSSGP arrived on wrong PCU[", rx_idx, "] instead of PCU[", pcu_idx, "]");
1008 }
Harald Welte3807ed12020-11-24 19:05:22 +01001009 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01001010 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001011 }
1012 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001013 f_shutdown(__FILE__, __LINE__, fail, log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Welte3807ed12020-11-24 19:05:22 +01001014 }
1015 }
1016}
1017
1018
Daniel Willmann423d8f42020-09-08 18:58:22 +02001019/* TODO:
1020 * Detach without Attach
1021 * SM procedures without attach / RAU
1022 * ATTACH / RAU
1023 ** with / without authentication
1024 ** with / without P-TMSI allocation
1025 * re-transmissions of LLC frames
1026 * PDP Context activation
1027 ** with different GGSN config in SGSN VTY
1028 ** with different PDP context type (v4/v6/v46)
1029 ** timeout from GGSN
1030 ** multiple / secondary PDP context
1031 */
1032
1033private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
1034 f_sleep(5.0);
1035 setverdict(pass);
1036}
1037
1038testcase TC_BVC_bringup() runs on test_CT {
Daniel Willmann423d8f42020-09-08 18:58:22 +02001039 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001040 f_start_handlers(refers(f_TC_BVC_bringup), testcasename(), 51);
Daniel Willmann423d8f42020-09-08 18:58:22 +02001041 f_cleanup();
1042}
1043
1044friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +01001045 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001046 timer T := 5.0;
1047 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +01001048 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001049 T.start;
1050 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001051 [] 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 +02001052 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
1053 }
Harald Welte16357a92020-11-17 18:20:00 +01001054 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Harald Welted5b7e742021-01-27 10:50:24 +01001055 f_shutdown(__FILE__, __LINE__, fail,
1056 log2str("SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001057 }
1058 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001059 f_shutdown(__FILE__, __LINE__, fail,
1060 log2str("No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001061 }
1062 }
1063 return '00'O;
1064}
1065
1066friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001067 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +02001068 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +01001069 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 +02001070 T.start;
1071 alt {
Harald Welte16357a92020-11-17 18:20:00 +01001072 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
1073 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Harald Welted5b7e742021-01-27 10:50:24 +01001074 f_shutdown(__FILE__, __LINE__, fail,
1075 log2str("RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001076 }
1077 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01001078 f_shutdown(__FILE__, __LINE__, fail,
1079 log2str("No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli));
Daniel Willmann423d8f42020-09-08 18:58:22 +02001080 }
1081 }
1082}
1083
1084
Harald Welte92686012020-11-15 21:45:49 +01001085/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
1086private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +01001087 var integer ran_idx := 0;
1088 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +01001089 var integer i;
1090
Harald Welte0d5fceb2020-11-29 16:04:07 +01001091 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +01001092 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +01001093 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 +01001094 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +01001095 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 +01001096
Harald Welte0d5fceb2020-11-29 16:04:07 +01001097 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001098 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +01001099 }
1100 setverdict(pass);
1101}
1102
1103testcase TC_ul_unitdata() runs on test_CT
1104{
Harald Welte92686012020-11-15 21:45:49 +01001105 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001106 f_start_handlers(refers(f_TC_ul_unitdata), testcasename(), 1);
Harald Welte92686012020-11-15 21:45:49 +01001107 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte92686012020-11-15 21:45:49 +01001108 f_cleanup();
1109}
1110
Harald Welte78d8db92020-11-15 23:27:27 +01001111/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
1112private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
1113 var integer i;
1114
Harald Welte0d5fceb2020-11-29 16:04:07 +01001115 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +01001116 var octetstring payload := f_rnd_octstring(i);
1117 var template (value) PDU_BSSGP pdu_tx :=
1118 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
1119 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1120 var template (present) PDU_BSSGP pdu_rx :=
1121 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
1122
Harald Welte0d5fceb2020-11-29 16:04:07 +01001123 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +01001124 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +01001125 }
1126 setverdict(pass);
1127}
1128
1129testcase TC_dl_unitdata() runs on test_CT
1130{
Harald Welte78d8db92020-11-15 23:27:27 +01001131 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001132 f_start_handlers(refers(f_TC_dl_unitdata), testcasename(), 2);
Harald Welte78d8db92020-11-15 23:27:27 +01001133 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte78d8db92020-11-15 23:27:27 +01001134 f_cleanup();
1135}
Harald Welte92686012020-11-15 21:45:49 +01001136
Harald Welte6dc2ac42020-11-16 09:16:17 +01001137private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
1138 var integer i;
1139
1140 for (i := 0; i < 10; i := i+1) {
1141 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
1142 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1143 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
1144
Harald Welte22ef5d92020-11-16 13:35:14 +01001145 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001146 }
1147 setverdict(pass);
1148}
1149testcase TC_ra_capability() runs on test_CT
1150{
Harald Welte6dc2ac42020-11-16 09:16:17 +01001151 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001152 f_start_handlers(refers(f_TC_ra_capability), testcasename(), 3);
Harald Welte6dc2ac42020-11-16 09:16:17 +01001153 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Welte6dc2ac42020-11-16 09:16:17 +01001154 f_cleanup();
1155}
1156
Daniel Willmannace3ece2020-11-16 19:53:26 +01001157private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
1158 var integer i;
1159 var OCT1 tag;
1160 for (i := 0; i < 10; i := i+1) {
1161 tag := int2oct(23 + i, 1);
1162 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
1163 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1164 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
1165
1166 f_pcu2sgsn(pdu_tx, pdu_rx);
1167
1168 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
1169 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1170 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
1171
1172 f_sgsn2pcu(pdu_tx, pdu_rx);
1173 }
1174 setverdict(pass);
1175}
1176testcase TC_ra_capability_upd() runs on test_CT
1177{
Daniel Willmannace3ece2020-11-16 19:53:26 +01001178 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001179 f_start_handlers(refers(f_TC_ra_capability_upd), testcasename(), 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +01001180 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmannace3ece2020-11-16 19:53:26 +01001181 f_cleanup();
1182}
1183
Daniel Willmann165d6612020-11-19 14:27:29 +01001184private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
1185 var integer i;
1186 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1187 for (i := 0; i < 10; i := i+1) {
1188 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
1189 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1190 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
1191
1192 f_pcu2sgsn(pdu_tx, pdu_rx);
1193 }
1194 setverdict(pass);
1195}
1196testcase TC_radio_status() runs on test_CT
1197{
Daniel Willmann165d6612020-11-19 14:27:29 +01001198 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001199 f_start_handlers(refers(f_TC_radio_status), testcasename(), 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001200 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann165d6612020-11-19 14:27:29 +01001201 f_cleanup();
1202}
1203
Harald Welte3148a962021-01-17 11:15:28 +01001204private function f_TC_radio_status_tmsi(charstring id) runs on BSSGP_ConnHdlr {
1205 var integer i;
1206 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1207 for (i := 0; i < 10; i := i+1) {
1208 var integer tmsi_int := oct2int(g_pars.p_tmsi);
1209 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1210 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1211 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, tmsi_int);
1212 f_pcu2sgsn(pdu_tx, pdu_rx);
1213 }
1214 setverdict(pass);
1215}
1216testcase TC_radio_status_tmsi() runs on test_CT
1217{
1218 f_init();
1219 f_start_handlers(refers(f_TC_radio_status_tmsi), testcasename(), 5);
1220 f_cleanup();
1221}
1222
1223private function f_TC_radio_status_imsi(charstring id) runs on BSSGP_ConnHdlr {
1224 var integer i;
1225 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
1226 for (i := 0; i < 10; i := i+1) {
1227 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1228 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1229 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(omit, cause, imsi := g_pars.imsi);
1230 f_pcu2any_sgsn(pdu_tx, pdu_rx);
1231 }
1232 setverdict(pass);
1233}
1234testcase TC_radio_status_imsi() runs on test_CT
1235{
1236 f_init();
1237 f_start_handlers(refers(f_TC_radio_status_imsi), testcasename(), 5);
1238 f_cleanup();
1239}
1240
1241
1242
Harald Welte99ed5072021-01-15 20:38:58 +01001243private function f_suspend_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1244 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001245runs on GlobalTest_CT
1246{
1247 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001248 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1249 nri_bitlen := mp_nri_bitlength);
1250 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001251 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1252 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1253 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1254 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1255
1256 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1257 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1258 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(suffix, 1));
1259 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1260
1261 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1262 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1263 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1264 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1265
1266 /* These messages are simple passed through so just also test sending NACK */
1267 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1268 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1269 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1270 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1271}
1272
Harald Weltec5c33732021-01-15 21:04:35 +01001273private function f_TC_suspend(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1274runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001275 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001276
Daniel Willmannfa67f492020-11-19 15:48:05 +01001277 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001278 f_suspend_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001279 }
1280 setverdict(pass);
1281}
Harald Welte3807ed12020-11-24 19:05:22 +01001282testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001283{
Harald Weltec5c33732021-01-15 21:04:35 +01001284 var integer sgsn_idx, nri_idx;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001285 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001286 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001287 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1288 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1289 f_TC_suspend(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1290 }
1291 }
Daniel Willmannfa67f492020-11-19 15:48:05 +01001292 f_cleanup();
1293}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001294
Harald Welte99ed5072021-01-15 20:38:58 +01001295private function f_resume_one(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx,
1296 integer suffix)
Harald Welte00963752021-01-15 20:33:11 +01001297runs on GlobalTest_CT
1298{
1299 var RoutingAreaIdentification ra_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id.ra_id;
Harald Welte99ed5072021-01-15 20:38:58 +01001300 var OCT4 p_tmsi := f_gen_tmsi(suffix, nri_v := mp_sgsn_nri[sgsn_idx][nri_idx],
1301 nri_bitlen := mp_nri_bitlength);
1302 var OCT4 tlli := f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
Harald Welte00963752021-01-15 20:33:11 +01001303 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1304 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1305 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1306 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1307
1308 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
1309 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1310 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
1311 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1312
1313 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1314 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1315 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(suffix, 1));
1316 f_global_pcu2sgsn(pdu_tx, pdu_rx, pcu_idx, sgsn_idx);
1317
1318 /* These messages are simple passed through so just also test sending NACK */
1319 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1320 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1321 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
1322 f_global_sgsn2pcu(pdu_tx, pdu_rx, sgsn_idx, pcu_idx);
1323}
1324
Harald Weltec5c33732021-01-15 21:04:35 +01001325private function f_TC_resume(integer sgsn_idx, integer nri_idx, integer pcu_idx, integer bvc_idx)
1326runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001327 var integer i;
1328
Daniel Willmann087a33d2020-11-19 15:58:43 +01001329 for (i := 0; i < 10; i := i+1) {
Harald Weltec5c33732021-01-15 21:04:35 +01001330 f_resume_one(sgsn_idx, nri_idx, pcu_idx, bvc_idx, suffix := i);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001331 }
1332 setverdict(pass);
1333}
Harald Welte3807ed12020-11-24 19:05:22 +01001334testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001335{
Harald Weltec5c33732021-01-15 21:04:35 +01001336 var integer sgsn_idx, nri_idx;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001337 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001338 f_global_init();
Harald Weltec5c33732021-01-15 21:04:35 +01001339 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
1340 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx+1) {
1341 f_TC_resume(sgsn_idx, nri_idx, pcu_idx:=0, bvc_idx:=0);
1342 }
1343 }
Daniel Willmann087a33d2020-11-19 15:58:43 +01001344 f_cleanup();
1345}
1346
Harald Weltef8ef0282020-11-18 12:16:59 +01001347/* test the load-sharing between multiple NS-VC on the BSS side */
1348private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1349 var integer i;
1350
1351 for (i := 0; i < 10; i := i+1) {
1352 var octetstring payload := f_rnd_octstring(i);
1353 var template (value) PDU_BSSGP pdu_tx :=
1354 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte09a1ce42021-01-16 11:18:38 +01001355 SGSN_PTP[g_pars.sgsn_idx].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001356 }
1357 setverdict(pass);
1358}
Harald Welte09a1ce42021-01-16 11:18:38 +01001359
1360private function f_TC_load_sharing_dl(integer sgsn_idx) runs on test_CT_NS
Harald Weltef8ef0282020-11-18 12:16:59 +01001361{
1362 const integer num_ue := 10;
1363 var BSSGP_ConnHdlr vc_conn[num_ue];
Harald Weltef8ef0282020-11-18 12:16:59 +01001364 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1365 * side so we get the raw NsUnitdataIndication and hence observe different
1366 * NSVCI */
1367 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1368 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1369
1370 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1371 * of the NS-VC is ALIVE/UNBLOCKED */
1372 f_sleep(3.0);
1373
1374 /* start parallel components generating DL-UNITDATA from the SGSN side */
1375 for (var integer i:= 0; i < num_ue; i := i+1) {
Harald Welte2ecbca82021-01-16 11:23:09 +01001376 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(),
Harald Welte09a1ce42021-01-16 11:18:38 +01001377 5+i, 30.0, sgsn_idx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001378 }
1379
1380 /* now start counting all the messages that were queued before */
1381 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1382 var ro_integer rx_count := { 0, 0, 0, 0 };
1383 timer T := 2.0;
1384 T.start;
1385 alt {
1386 [] as_NsUdiCount(0, rx_count);
1387 [] as_NsUdiCount(1, rx_count);
1388 [] as_NsUdiCount(2, rx_count);
1389 [] as_NsUdiCount(3, rx_count);
1390 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1391 [] NS.receive(NsStatusIndication:?) { repeat; }
1392 [] NS.receive {
Harald Welted5b7e742021-01-27 10:50:24 +01001393 f_shutdown(__FILE__, __LINE__, fail, "Rx unexpected NS");
Harald Weltef8ef0282020-11-18 12:16:59 +01001394 }
1395 [] T.timeout {
1396 }
1397 }
1398 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1399 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1400 if (rx_count[i] == 0) {
1401 setverdict(fail, "Data not shared over all NSVC");
1402 }
1403 }
Harald Welte09a1ce42021-01-16 11:18:38 +01001404}
1405
1406testcase TC_load_sharing_dl() runs on test_CT_NS
1407{
1408 var integer sgsn_idx, nri_idx;
1409 f_init();
1410 for (sgsn_idx:=0; sgsn_idx < NUM_SGSN; sgsn_idx:=sgsn_idx+1) {
1411 f_TC_load_sharing_dl(sgsn_idx);
1412 }
Harald Weltef8ef0282020-11-18 12:16:59 +01001413 setverdict(pass);
1414}
1415private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1416 var NsUnitdataIndication udi;
1417 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1418 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1419 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1420 repeat;
1421 }
1422}
1423type component test_CT_NS extends test_CT {
1424 port NS_PT NS;
1425};
1426
1427
Harald Welte0e188242020-11-22 21:46:48 +01001428/***********************************************************************
1429 * PAGING PS procedure
1430 ***********************************************************************/
1431
1432private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1433 boolean use_sig := false)
1434runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1435 var template (value) PDU_BSSGP pdu_tx;
1436 var template (present) PDU_BSSGP pdu_rx;
1437 /* we always specify '0' as BVCI in the templates below, as we override it with
1438 * 'p4' later anyway */
1439 pdu_rx := tr_BSSGP_PS_PAGING(0);
1440 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1441 if (ispresent(g_pars.p_tmsi)) {
1442 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1443 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1444 } else {
1445 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1446 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1447 }
1448 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1449 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1450 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001451 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001452 } else {
1453 SGSN_SIG[sgsn_idx].send(pdu_tx);
1454 }
1455 return pdu_rx;
1456}
1457
1458/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1459 * specified PCU index */
1460private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1461 boolean use_sig := false,integer pcu_idx := 0)
1462runs on BSSGP_ConnHdlr {
1463 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001464 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001465 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1466 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1467 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1468 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1469 timer T := 2.0;
1470 T.start;
1471 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001472 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001473 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001474 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001475 repeat;
1476 }
1477 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1478 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1479 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001480 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001481 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001482 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001483 repeat;
1484 }
Harald Welte158becf2020-12-09 12:32:32 +01001485 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001486 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1487 }
Harald Welte158becf2020-12-09 12:32:32 +01001488 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001489 setverdict(fail, "Paging received on unexpected BVC");
1490 }
1491 [] any from PCU_SIG.receive(exp_rx) {
1492 setverdict(fail, "Paging received on unexpected BVC");
1493 }
Harald Welte158becf2020-12-09 12:32:32 +01001494 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001495 setverdict(fail, "Different Paging than expected received PTP BVC");
1496 }
1497 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1498 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1499 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001500 [not test_done] T.timeout {
1501 setverdict(fail, "Timeout waiting for paging");
1502 }
1503 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001504 }
1505}
1506
Harald Welte7462a592020-11-23 22:07:07 +01001507/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1508private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1509 boolean use_sig := false)
1510runs on BSSGP_ConnHdlr {
1511 var template (present) PDU_BSSGP exp_rx;
1512 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1513 /* Expect paging to propagate to no BSS */
1514 timer T := 2.0;
1515 T.start;
1516 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001517 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001518 setverdict(fail, "Paging received on unexpected BVC");
1519 }
1520 [] any from PCU_SIG.receive(exp_rx) {
1521 setverdict(fail, "Paging received on unexpected BVC");
1522 }
Harald Welte158becf2020-12-09 12:32:32 +01001523 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001524 setverdict(fail, "Different Paging received on PTP BVC");
1525 }
1526 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1527 setverdict(fail, "Different Paging received on SIGNALING BVC");
1528 }
1529 [] T.timeout {
1530 setverdict(pass);
1531 }
1532 }
1533}
1534
Harald Welte0e188242020-11-22 21:46:48 +01001535private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1536{
1537 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1538 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001539 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001540}
1541testcase TC_paging_ps_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001542 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001543 f_start_handlers(refers(f_TC_paging_ps_ptp_bss), testcasename(), 9);
Harald Welte0e188242020-11-22 21:46:48 +01001544 f_cleanup();
1545}
1546
1547/* PS-PAGING on PTP-BVC for Location Area */
1548private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1549{
1550 var template (present) PDU_BSSGP exp_rx;
1551 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1552 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001553 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001554}
1555testcase TC_paging_ps_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001556 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001557 f_start_handlers(refers(f_TC_paging_ps_ptp_lac), testcasename(), 10);
Harald Welte0e188242020-11-22 21:46:48 +01001558 f_cleanup();
1559}
1560
Harald Welte7462a592020-11-23 22:07:07 +01001561/* PS-PAGING on PTP-BVC for unknown Location Area */
1562private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1563{
1564 var GSM_Types.LocationAreaIdentification unknown_la := {
1565 mcc_mnc := '567F99'H,
1566 lac := 33333
1567 };
1568 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001569 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001570}
1571testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001572 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001573 f_start_handlers(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001574 f_cleanup();
1575}
1576
Harald Welte0e188242020-11-22 21:46:48 +01001577/* PS-PAGING on PTP-BVC for Routeing Area */
1578private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1579{
1580 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1581 * at that BVC (cell) only, and paging all over the BSS area is not possible */
Daniel Willmann2a330672021-01-18 18:50:02 +01001582 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001583}
1584testcase TC_paging_ps_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001585 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001586 f_start_handlers(refers(f_TC_paging_ps_ptp_rac), testcasename(), 11);
Harald Welte0e188242020-11-22 21:46:48 +01001587 f_cleanup();
1588}
1589
Harald Welte7462a592020-11-23 22:07:07 +01001590/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1591private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1592{
1593 var RoutingAreaIdentification unknown_ra := {
1594 lai := {
1595 mcc_mnc := '567F99'H,
1596 lac := 33333
1597 },
1598 rac := 254
1599 };
1600 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
Daniel Willmann2a330672021-01-18 18:50:02 +01001601 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001602}
1603testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001604 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001605 f_start_handlers(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001606 f_cleanup();
1607}
1608
Harald Welte0e188242020-11-22 21:46:48 +01001609/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1610private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1611{
1612 /* this should be the normal case for MS in READY MM state after a lower layer failure */
Daniel Willmann2a330672021-01-18 18:50:02 +01001613 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Welte0e188242020-11-22 21:46:48 +01001614}
1615testcase TC_paging_ps_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001616 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001617 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12);
Harald Welte0e188242020-11-22 21:46:48 +01001618 f_cleanup();
1619}
1620
Harald Welteb5a04aa2021-01-16 13:04:40 +01001621
1622/* PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1623testcase TC_paging_ps_ptp_bvci_imsi() runs on test_CT {
1624 f_init();
1625 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci), testcasename(), 12, have_ptmsi:=false);
1626 f_cleanup();
1627}
1628
Harald Weltecf200072021-01-16 15:20:46 +01001629/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) */
1630testcase TC_paging_ps_reject_ptp_bvci() runs on test_CT {
1631 f_init();
1632 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16);
1633 f_cleanup();
1634}
1635
1636/* Rejected PS-PAGING on PTP-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1637private function f_TC_paging_ps_reject_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1638{
1639 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann2a330672021-01-18 18:50:02 +01001640 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), g_pars.sgsn_idx, false, 0);
Harald Weltecf200072021-01-16 15:20:46 +01001641 /* then simulate the PS-PAGING-REJECT from the PCU */
1642 f_send_paging_ps_rej(use_sig:=false);
1643}
1644testcase TC_paging_ps_reject_ptp_bvci_imsi() runs on test_CT {
1645 f_init();
1646 f_start_handlers(refers(f_TC_paging_ps_reject_ptp_bvci), testcasename(), 16, have_ptmsi:=false);
1647 f_cleanup();
1648}
Harald Welteb5a04aa2021-01-16 13:04:40 +01001649
Harald Welte7462a592020-11-23 22:07:07 +01001650/* PS-PAGING on PTP-BVC for unknown BVCI */
1651private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1652{
1653 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
Daniel Willmann2a330672021-01-18 18:50:02 +01001654 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, false, 0);
Harald Welte7462a592020-11-23 22:07:07 +01001655}
1656testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001657 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001658 f_start_handlers(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001659 f_cleanup();
1660}
1661
Harald Welte7595d562021-01-16 19:09:20 +01001662/* DUMMY PAGING PS on PTP BVC */
1663private function f_TC_dummy_paging_ps_ptp(charstring id) runs on BSSGP_ConnHdlr
1664{
1665 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1666 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := false);
1667 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1668 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := false)
1669}
1670testcase TC_dummy_paging_ps_ptp() runs on test_CT {
1671 f_init();
1672 f_start_handlers(refers(f_TC_dummy_paging_ps_ptp), testcasename(), 11);
1673 f_cleanup();
1674}
1675
Harald Welte0e188242020-11-22 21:46:48 +01001676/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1677private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1678runs on BSSGP_ConnHdlr {
1679[] PCU_SIG[pcu_idx].receive(exp_rx) {
1680 if (ro_integer_contains(roi, pcu_idx)) {
1681 setverdict(fail, "Received multiple paging on same SIG BVC");
1682 }
1683 roi := roi & { pcu_idx };
1684 repeat;
1685 }
Harald Welte158becf2020-12-09 12:32:32 +01001686[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001687 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1688 }
1689[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1690 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1691 }
Harald Welte158becf2020-12-09 12:32:32 +01001692[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001693 setverdict(fail, "Different Paging than expected received PTP BVC");
1694 }
1695}
1696
1697type record of default ro_default;
1698
1699/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1700private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1701 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1702{
1703 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann193e1a02021-01-17 12:55:53 +01001704 exp_rx := f_send_paging_ps(p4, sgsn_idx, true);
Harald Welte0e188242020-11-22 21:46:48 +01001705
1706 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1707 var ro_default defaults := {};
1708 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1709 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1710 defaults := defaults & { d };
1711 }
1712 f_sleep(2.0);
1713 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1714 deactivate(defaults[i]);
1715 }
1716 log("Paging received on PCU ", g_roi);
1717
1718 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1719 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1720 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1721 if (exp_on_i and not rx_on_i) {
1722 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1723 }
1724 if (not exp_on_i and rx_on_i) {
1725 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1726 }
1727 }
1728 setverdict(pass);
1729}
1730
Harald Weltecf200072021-01-16 15:20:46 +01001731/* Send PAGING-PS-REJECT on SIG BVC, expect it to arrive on the "right" SGSN */
1732private function f_send_paging_ps_rej(boolean use_sig := true, integer pcu_idx := 0) runs on BSSGP_ConnHdlr
1733{
1734 var template (value) PDU_BSSGP pdu_tx;
1735 var template (present) PDU_BSSGP exp_rx;
1736 var PDU_BSSGP pdu_rx;
1737 timer T := 5.0;
1738 var template (omit) GsmTmsi tmsi_int := omit;
1739
1740 if (ispresent(g_pars.p_tmsi)) {
1741 tmsi_int := oct2int(g_pars.p_tmsi);
1742 }
1743
1744 pdu_tx := ts_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1745 exp_rx := tr_BSSGP_PAGING_PS_REJ(g_pars.imsi, 23, 42, tmsi_int);
1746
1747 if (use_sig) {
1748 PCU_SIG[pcu_idx].send(pdu_tx);
1749 } else {
1750 PCU_PTP[pcu_idx].send(pdu_tx);
1751 }
1752 T.start;
1753 alt {
1754 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1755 setverdict(pass);
1756 }
1757 [use_sig] SGSN_SIG[g_pars.sgsn_idx].receive {
1758 setverdict(fail, "Unexpected PDU on SGSN");
1759 }
1760 [use_sig] any from SGSN_SIG.receive(exp_rx) -> value pdu_rx {
1761 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1762 }
1763 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive(exp_rx) -> value pdu_rx {
1764 setverdict(pass);
1765 }
1766 [not use_sig] SGSN_PTP[g_pars.sgsn_idx].receive {
1767 setverdict(fail, "Unexpected PDU on SGSN");
1768 }
1769 [not use_sig] any from SGSN_PTP.receive(exp_rx) -> value pdu_rx {
1770 setverdict(fail, "PAGING-PS-REJECT arrived on wrong SGSN");
1771 }
1772 [] T.timeout {
1773 setverdict(fail, "Timeout waiting for PAGING-PS-REJECT");
1774 }
1775 }
1776}
1777
Harald Welte0e188242020-11-22 21:46:48 +01001778/* PS-PAGING on SIG-BVC for BSS Area */
1779private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1780{
1781 /* we expect the paging to arrive on all three NSE */
Daniel Willmann43320442021-01-17 14:07:05 +01001782 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, g_pars.sgsn_idx, {0, 1, 2});
Harald Welte0e188242020-11-22 21:46:48 +01001783}
1784testcase TC_paging_ps_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001785 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001786 f_start_handlers(refers(f_TC_paging_ps_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01001787 f_cleanup();
1788}
1789
1790/* PS-PAGING on SIG-BVC for Location Area */
1791private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1792{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001793 /* The first LAC (13135) is shared by all three NSEs */
Daniel Willmann43320442021-01-17 14:07:05 +01001794 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 +01001795 /* Reset state */
1796 g_roi := {};
1797 /* Make LAC (13300) available on pcu index 2 */
1798 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001799 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 +01001800}
1801testcase TC_paging_ps_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001802 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001803 f_start_handlers(refers(f_TC_paging_ps_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01001804 f_cleanup();
1805}
1806
Harald Welte7462a592020-11-23 22:07:07 +01001807/* PS-PAGING on SIG-BVC for unknown Location Area */
1808private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1809{
1810 var GSM_Types.LocationAreaIdentification unknown_la := {
1811 mcc_mnc := '567F99'H,
1812 lac := 33333
1813 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001814 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001815}
1816testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001817 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001818 f_start_handlers(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001819 f_cleanup();
1820}
1821
Harald Welte0e188242020-11-22 21:46:48 +01001822/* PS-PAGING on SIG-BVC for Routeing Area */
1823private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1824{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001825 /* Only PCU index 0 has a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001826 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 +01001827 g_roi := {};
1828 /* PCU index 1 and 2 have a matching BVC with the RA ID */
Daniel Willmann43320442021-01-17 14:07:05 +01001829 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 +01001830 g_roi := {};
1831 /* PCU index 2 has two matching BVCs with the RA ID */
1832 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
Daniel Willmann43320442021-01-17 14:07:05 +01001833 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 +01001834}
1835testcase TC_paging_ps_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001836 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001837 f_start_handlers(refers(f_TC_paging_ps_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01001838 f_cleanup();
1839}
1840
Harald Welte7462a592020-11-23 22:07:07 +01001841/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1842private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1843{
1844 var RoutingAreaIdentification unknown_ra := {
1845 lai := {
1846 mcc_mnc := '567F99'H,
1847 lac := 33333
1848 },
1849 rac := 254
1850 };
Daniel Willmann2a330672021-01-18 18:50:02 +01001851 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001852}
1853testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001854 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001855 f_start_handlers(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001856 f_cleanup();
1857}
1858
Harald Welte0e188242020-11-22 21:46:48 +01001859/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1860private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1861{
Daniel Willmann43320442021-01-17 14:07:05 +01001862 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 +01001863}
1864testcase TC_paging_ps_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01001865 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001866 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01001867 f_cleanup();
1868}
1869
Harald Welteb5a04aa2021-01-16 13:04:40 +01001870/* PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1871testcase TC_paging_ps_sig_bvci_imsi() runs on test_CT {
1872 f_init();
1873 f_start_handlers(refers(f_TC_paging_ps_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1874 f_cleanup();
1875}
1876
Harald Weltecf200072021-01-16 15:20:46 +01001877/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) */
1878private function f_TC_paging_ps_reject_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1879{
1880 /* first send the PS-PAGING from SGSN -> PCU */
Daniel Willmann43320442021-01-17 14:07:05 +01001881 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 +01001882 /* then simulate the PS-PAGING-REJECT from the PCU */
1883 f_send_paging_ps_rej(use_sig:=true);
1884
1885}
1886testcase TC_paging_ps_reject_sig_bvci() runs on test_CT {
1887 f_init();
1888 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16);
1889 f_cleanup();
1890}
1891
1892/* Rejected PS-PAGING on SIG-BVC for BVCI (one cell) using IMSI only (no P-TMSI allocated) */
1893testcase TC_paging_ps_reject_sig_bvci_imsi() runs on test_CT {
1894 f_init();
1895 f_start_handlers(refers(f_TC_paging_ps_reject_sig_bvci), testcasename(), 16, have_ptmsi:=false);
1896 f_cleanup();
1897}
1898
Harald Welte7462a592020-11-23 22:07:07 +01001899/* PS-PAGING on SIG-BVC for unknown BVCI */
1900private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1901{
Daniel Willmann2a330672021-01-18 18:50:02 +01001902 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), g_pars.sgsn_idx, true);
Harald Welte7462a592020-11-23 22:07:07 +01001903}
1904testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01001905 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01001906 f_start_handlers(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01001907 f_cleanup();
1908}
1909
Harald Welte7595d562021-01-16 19:09:20 +01001910/* DUMMY PAGING PS on SIG BVC */
1911private function f_TC_dummy_paging_ps_sig(charstring id) runs on BSSGP_ConnHdlr
1912{
1913 f_sgsn2pcu(ts_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit),
1914 tr_BSSGP_DUMMY_PAGING_PS(g_pars.imsi, omit), use_sig := true);
1915 f_pcu2sgsn(ts_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5),
1916 tr_BSSGP_DUMMY_PAGING_PS_RESP(g_pars.imsi, 1, 5), use_sig := true)
1917}
1918testcase TC_dummy_paging_ps_sig() runs on test_CT {
1919 f_init();
1920 f_start_handlers(refers(f_TC_dummy_paging_ps_sig), testcasename(), 11);
1921 f_cleanup();
1922}
1923
Harald Welte7462a592020-11-23 22:07:07 +01001924
Harald Welte0e188242020-11-22 21:46:48 +01001925
1926/***********************************************************************
1927 * PAGING CS procedure
1928 ***********************************************************************/
1929
1930private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1931 boolean use_sig := false)
1932runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1933 var template (value) PDU_BSSGP pdu_tx;
1934 var template (present) PDU_BSSGP pdu_rx;
1935 /* we always specify '0' as BVCI in the templates below, as we override it with
1936 * 'p4' later anyway */
1937 pdu_rx := tr_BSSGP_CS_PAGING(0);
1938 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1939 if (ispresent(g_pars.p_tmsi)) {
1940 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1941 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1942 } else {
1943 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1944 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1945 }
1946 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1947 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1948 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001949 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001950 } else {
1951 SGSN_SIG[sgsn_idx].send(pdu_tx);
1952 }
1953 return pdu_rx;
1954}
1955
1956/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1957 * specified PCU index */
1958private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1959 boolean use_sig := false,integer pcu_idx := 0)
1960runs on BSSGP_ConnHdlr {
1961 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001962 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001963 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1964 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1965 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1966 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1967 timer T := 2.0;
1968 T.start;
1969 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001970 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001971 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001972 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001973 repeat;
1974 }
1975 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1976 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1977 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001978 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001979 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001980 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001981 repeat;
1982 }
Harald Welte158becf2020-12-09 12:32:32 +01001983 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001984 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1985 }
Harald Welte158becf2020-12-09 12:32:32 +01001986 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001987 setverdict(fail, "Paging received on unexpected BVC");
1988 }
1989 [] any from PCU_SIG.receive(exp_rx) {
1990 setverdict(fail, "Paging received on unexpected BVC");
1991 }
Harald Welte158becf2020-12-09 12:32:32 +01001992 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001993 setverdict(fail, "Different Paging than expected received PTP BVC");
1994 }
1995 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1996 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1997 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001998 [not test_done] T.timeout {
1999 setverdict(fail, "Timeout while waiting for paging")
2000 }
2001 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01002002 }
2003}
2004
Harald Welte7462a592020-11-23 22:07:07 +01002005/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
2006private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2007 boolean use_sig := false)
2008runs on BSSGP_ConnHdlr {
2009 var template (present) PDU_BSSGP exp_rx;
2010 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
2011 /* Expect paging to propagate to no BSS */
2012 timer T := 2.0;
2013 T.start;
2014 alt {
Harald Welte158becf2020-12-09 12:32:32 +01002015 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01002016 setverdict(fail, "Paging received on unexpected BVC");
2017 }
2018 [] any from PCU_SIG.receive(exp_rx) {
2019 setverdict(fail, "Paging received on unexpected BVC");
2020 }
Harald Welte158becf2020-12-09 12:32:32 +01002021 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01002022 setverdict(fail, "Different Paging received on PTP BVC");
2023 }
2024 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
2025 setverdict(fail, "Different Paging received on SIGNALING BVC");
2026 }
2027 [] T.timeout {
2028 setverdict(pass);
2029 }
2030 }
2031}
2032
Harald Welte0e188242020-11-22 21:46:48 +01002033private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
2034{
2035 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2036 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2037 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
2038}
2039testcase TC_paging_cs_ptp_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002040 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002041 f_start_handlers(refers(f_TC_paging_cs_ptp_bss), testcasename(), 17);
Harald Welte0e188242020-11-22 21:46:48 +01002042 f_cleanup();
2043}
2044
2045/* CS-PAGING on PTP-BVC for Location Area */
2046private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
2047{
2048 var template (present) PDU_BSSGP exp_rx;
2049 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2050 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2051 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
2052}
2053testcase TC_paging_cs_ptp_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002054 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002055 f_start_handlers(refers(f_TC_paging_cs_ptp_lac), testcasename(), 18);
Harald Welte0e188242020-11-22 21:46:48 +01002056 f_cleanup();
2057}
2058
Harald Welte7462a592020-11-23 22:07:07 +01002059/* CS-PAGING on PTP-BVC for unknown Location Area */
2060private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2061{
2062 var GSM_Types.LocationAreaIdentification unknown_la := {
2063 mcc_mnc := '567F99'H,
2064 lac := 33333
2065 };
2066 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
2067 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
2068}
2069testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002070 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002071 f_start_handlers(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002072 f_cleanup();
2073}
2074
Harald Welte0e188242020-11-22 21:46:48 +01002075/* CS-PAGING on PTP-BVC for Routeing Area */
2076private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
2077{
2078 /* doesn't really make sense: Sending to a single BVCI means the message ends up
2079 * at that BVC (cell) only, and paging all over the BSS area is not possible */
2080 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
2081}
2082testcase TC_paging_cs_ptp_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002083 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002084 f_start_handlers(refers(f_TC_paging_cs_ptp_rac), testcasename(), 19);
Harald Welte0e188242020-11-22 21:46:48 +01002085 f_cleanup();
2086}
2087
Harald Welte7462a592020-11-23 22:07:07 +01002088/* CS-PAGING on PTP-BVC for unknown Routeing Area */
2089private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2090{
2091 var RoutingAreaIdentification unknown_ra := {
2092 lai := {
2093 mcc_mnc := '567F99'H,
2094 lac := 33333
2095 },
2096 rac := 254
2097 };
2098 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
2099 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
2100}
2101testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002102 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002103 f_start_handlers(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002104 f_cleanup();
2105}
2106
Harald Welte0e188242020-11-22 21:46:48 +01002107/* CS-PAGING on PTP-BVC for BVCI (one cell) */
2108private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
2109{
2110 /* this should be the normal case for MS in READY MM state after a lower layer failure */
2111 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
2112}
2113testcase TC_paging_cs_ptp_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002114 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002115 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci), testcasename(), 20);
Harald Welte0e188242020-11-22 21:46:48 +01002116 f_cleanup();
2117}
2118
Harald Welte7462a592020-11-23 22:07:07 +01002119/* CS-PAGING on PTP-BVC for unknown BVCI */
2120private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2121{
2122 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
2123 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
2124}
2125testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002126 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002127 f_start_handlers(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002128 f_cleanup();
2129}
2130
Harald Welte0e188242020-11-22 21:46:48 +01002131/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
2132private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
2133 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
2134{
2135 var template (present) PDU_BSSGP exp_rx;
2136 exp_rx := f_send_paging_cs(p4, 0, true);
2137
2138 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
2139 var ro_default defaults := {};
2140 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2141 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
2142 defaults := defaults & { d };
2143 }
2144 f_sleep(2.0);
2145 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2146 deactivate(defaults[i]);
2147 }
2148 log("Paging received on PCU ", g_roi);
2149
2150 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
2151 var boolean rx_on_i := ro_integer_contains(g_roi, i);
2152 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
2153 if (exp_on_i and not rx_on_i) {
2154 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
2155 }
2156 if (not exp_on_i and rx_on_i) {
2157 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
2158 }
2159 }
2160 setverdict(pass);
2161}
2162
2163/* CS-PAGING on SIG-BVC for BSS Area */
2164private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
2165{
2166 /* we expect the paging to arrive on all three NSE */
2167 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
2168}
2169testcase TC_paging_cs_sig_bss() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002170 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002171 f_start_handlers(refers(f_TC_paging_cs_sig_bss), testcasename(), 13);
Harald Welte0e188242020-11-22 21:46:48 +01002172 f_cleanup();
2173}
2174
2175/* CS-PAGING on SIG-BVC for Location Area */
2176private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
2177{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002178 /* The first LAC (13135) is shared by all three NSEs */
2179 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
2180 /* Reset state */
2181 g_roi := {};
2182 /* Make LAC (13300) available on pcu index 2 */
2183 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2184 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 +01002185}
2186testcase TC_paging_cs_sig_lac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002187 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002188 f_start_handlers(refers(f_TC_paging_cs_sig_lac), testcasename(), 14);
Harald Welte0e188242020-11-22 21:46:48 +01002189 f_cleanup();
2190}
2191
Harald Welte7462a592020-11-23 22:07:07 +01002192/* CS-PAGING on SIG-BVC for unknown Location Area */
2193private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
2194{
2195 var GSM_Types.LocationAreaIdentification unknown_la := {
2196 mcc_mnc := '567F99'H,
2197 lac := 33333
2198 };
2199 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
2200}
2201testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002202 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002203 f_start_handlers(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002204 f_cleanup();
2205}
2206
Harald Welte0e188242020-11-22 21:46:48 +01002207/* CS-PAGING on SIG-BVC for Routeing Area */
2208private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
2209{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01002210 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01002211 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 +01002212 g_roi := {};
2213 /* PCU index 1 and 2 have a matching BVC with the RA ID */
2214 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
2215 g_roi := {};
2216 /* PCU index 2 has two matching BVCs with the RA ID */
2217 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
2218 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 +01002219}
2220testcase TC_paging_cs_sig_rac() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002221 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002222 f_start_handlers(refers(f_TC_paging_cs_sig_rac), testcasename(), 15);
Harald Welte0e188242020-11-22 21:46:48 +01002223 f_cleanup();
2224}
2225
Harald Welte7462a592020-11-23 22:07:07 +01002226/* CS-PAGING on SIG-BVC for unknown Routeing Area */
2227private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
2228{
2229 var RoutingAreaIdentification unknown_ra := {
2230 lai := {
2231 mcc_mnc := '567F99'H,
2232 lac := 33333
2233 },
2234 rac := 254
2235 };
2236 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
2237}
2238testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002239 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002240 f_start_handlers(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002241 f_cleanup();
2242}
2243
Harald Welte0e188242020-11-22 21:46:48 +01002244/* CS-PAGING on SIG-BVC for BVCI (one cell) */
2245private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
2246{
2247 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
2248}
2249testcase TC_paging_cs_sig_bvci() runs on test_CT {
Harald Welte0e188242020-11-22 21:46:48 +01002250 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002251 f_start_handlers(refers(f_TC_paging_cs_sig_bvci), testcasename(), 16);
Harald Welte0e188242020-11-22 21:46:48 +01002252 f_cleanup();
2253}
2254
Harald Welte7462a592020-11-23 22:07:07 +01002255/* CS-PAGING on SIG-BVC for unknown BVCI */
2256private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
2257{
2258 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
2259}
2260testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
Harald Welte7462a592020-11-23 22:07:07 +01002261 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002262 f_start_handlers(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), 11);
Harald Welte7462a592020-11-23 22:07:07 +01002263 f_cleanup();
2264}
2265
Harald Welte4f91c3b2020-12-09 12:25:51 +01002266/***********************************************************************
2267 * FLUSH-LL procedure
2268 ***********************************************************************/
2269
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002270private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
2271 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2272 var integer i;
2273 for (i := 0; i < 10; i := i+1) {
2274 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2275 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2276 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
2277
2278 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2279
2280 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2281 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2282 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2283
2284 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2285 }
2286 setverdict(pass);
2287}
2288testcase TC_flush_ll() runs on test_CT
2289{
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002290 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002291 f_start_handlers(refers(f_TC_flush_ll), testcasename(), 6);
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002292 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002293 f_cleanup();
2294}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002295
Harald Welte4f91c3b2020-12-09 12:25:51 +01002296/***********************************************************************
2297 * SGSN-INVOKE-TRACE procedure
2298 ***********************************************************************/
2299
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002300private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2301runs on GlobalTest_CT {
2302[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2303 if (ro_integer_contains(roi, pcu_idx)) {
2304 setverdict(fail, "Received multiple on same SIG BVC");
2305 }
2306 roi := roi & { pcu_idx };
2307 repeat;
2308 }
2309}
2310/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2311testcase TC_trace() runs on GlobalTest_CT
2312{
2313 var BSSGP_ConnHdlr vc_conn;
2314 f_init();
2315 f_global_init();
2316
2317 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2318 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2319
2320 var ro_default defaults := {};
2321 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2322 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2323 }
2324 G_SGSN[0].send(pdu_tx);
2325 f_sleep(2.0);
2326 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2327 deactivate(defaults[i]);
2328 }
2329
2330 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2331 if (not ro_integer_contains(g_roi, i)) {
2332 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2333 }
2334 }
2335 setverdict(pass);
2336
2337 f_cleanup();
2338}
2339
Harald Welte4f91c3b2020-12-09 12:25:51 +01002340/***********************************************************************
2341 * LLC-DISCARDED procedure
2342 ***********************************************************************/
2343
Harald Weltec0351d12020-11-27 22:49:02 +01002344private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2345 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2346
2347 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2348 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2349 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2350
2351 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2352
2353 setverdict(pass);
2354}
2355/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2356testcase TC_llc_discarded() runs on test_CT
2357{
Harald Weltec0351d12020-11-27 22:49:02 +01002358 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002359 f_start_handlers(refers(f_TC_llc_discarded), testcasename(), 6);
Harald Weltec0351d12020-11-27 22:49:02 +01002360 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltec0351d12020-11-27 22:49:02 +01002361 f_cleanup();
2362}
2363
Harald Welte4f91c3b2020-12-09 12:25:51 +01002364/***********************************************************************
2365 * OVERLOAD procedure
2366 ***********************************************************************/
2367
Harald Weltef20af412020-11-28 16:11:11 +01002368/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2369testcase TC_overload() runs on GlobalTest_CT
2370{
2371 f_init();
2372 f_global_init();
2373
2374 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2375 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2376
2377 var ro_default defaults := {};
2378 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2379 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2380 }
2381 G_SGSN[0].send(pdu_tx);
2382 f_sleep(2.0);
2383 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2384 deactivate(defaults[i]);
2385 }
2386
2387 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2388 if (not ro_integer_contains(g_roi, i)) {
2389 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2390 }
2391 }
2392 setverdict(pass);
2393
2394 f_cleanup();
2395}
2396
Harald Welte4f91c3b2020-12-09 12:25:51 +01002397/***********************************************************************
2398 * BVC-BLOCK / BVC-UNBLOCK procedure
2399 ***********************************************************************/
2400
Harald Welte239aa502020-11-24 23:14:20 +01002401private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2402{
2403 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2404 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2405 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2406
2407 SGSN_MGMT.clear;
2408 PCU_MGMT.clear;
2409
2410 /* block the PTP BVC from the PCU side */
2411 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2412 /* expect state on both PCU and SGSN side to change */
2413 interleave {
2414 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2415 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2416 }
2417 setverdict(pass);
2418}
2419testcase TC_bvc_block_ptp() runs on test_CT
2420{
2421 f_init();
2422 f_sleep(1.0);
2423 f_block_ptp_bvc_from_pcu(0, 0);
2424 f_cleanup();
2425}
2426
2427private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2428{
2429 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2430 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2431 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2432
2433 SGSN_MGMT.clear;
2434 PCU_MGMT.clear;
2435
2436 /* block the PTP BVC from the PCU side */
2437 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2438 /* expect state on both PCU and SGSN side to change */
2439 interleave {
2440 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2441 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2442 }
2443 setverdict(pass);
2444}
2445testcase TC_bvc_unblock_ptp() runs on test_CT
2446{
2447 f_init();
2448 f_sleep(1.0);
2449 f_block_ptp_bvc_from_pcu(0, 0);
2450 f_sleep(1.0);
2451 f_unblock_ptp_bvc_from_pcu(0, 0);
2452 f_cleanup();
2453}
2454
Harald Welte4f91c3b2020-12-09 12:25:51 +01002455/***********************************************************************
2456 * BVC-RESET procedure
2457 ***********************************************************************/
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002458private altstep as_count_bvc_reset(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
2459runs on test_CT {
2460 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2461 [] SGSN_MGMT.receive(BssgpResetIndication:{bvci}) from sgsn_bvc_ct {
2462 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
2463 repeat;
2464 }
2465}
Harald Welte60a8ec72020-11-25 17:12:53 +01002466private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2467[] pt.receive(BssgpStatusIndication:?) { repeat; }
2468}
2469private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2470 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2471 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2472 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2473 }
2474 }
2475 return null;
2476}
2477private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2478{
2479 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2480 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2481 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002482 var ro_default defaults;
2483 var integer i;
Harald Welte60a8ec72020-11-25 17:12:53 +01002484
2485 SGSN_MGMT.clear;
2486 PCU_MGMT.clear;
2487
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002488 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2489 g_roroi[i] := {};
2490 }
2491
Harald Welte60a8ec72020-11-25 17:12:53 +01002492 /* block the PTP BVC from the PCU side */
2493 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002494
Harald Welte60a8ec72020-11-25 17:12:53 +01002495 /* expect state on both PCU and SGSN side to change */
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002496 defaults := { activate(as_ignore_status(SGSN_MGMT)) };
2497
2498 /* Activate altsteps: One for each SGSN */
2499 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2500 var default d := activate(as_count_bvc_reset(i, bvc_cfg.bvci, g_roroi));
2501 defaults := defaults & { d };
Harald Welte60a8ec72020-11-25 17:12:53 +01002502 }
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002503
2504 timer T := 3.0;
2505 T.start;
2506 alt {
2507 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct {
2508 g_roi := g_roi & { bvc_cfg.bvci };
2509 repeat;
2510 }
2511 [] T.timeout;
2512 }
2513
2514 for (i := 0; i < lengthof(defaults); i := i+1) {
2515 deactivate(defaults[i]);
2516 }
2517
2518 /* Check if BVC-RESET was received at all SGSNs */
2519 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
2520 if (not ro_integer_contains(g_roroi[i], bvc_cfg.bvci)) {
2521 setverdict(fail, "Missing SGSN[", i, "] BVC-BLOCK of BVCI=", bvc_cfg.bvci);
2522 }
2523 }
2524
Harald Welte60a8ec72020-11-25 17:12:53 +01002525 setverdict(pass);
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002526 f_cleanup();
Harald Welte60a8ec72020-11-25 17:12:53 +01002527}
2528/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2529testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2530{
2531 f_init();
2532 f_sleep(3.0);
2533 f_reset_ptp_bvc_from_pcu(0, 0);
2534 f_cleanup();
2535}
2536
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002537private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout roro_integer roroi)
Harald Welte16786e92020-11-27 19:11:56 +01002538runs on test_CT {
2539 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2540 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002541 roroi[sgsn_idx] := roroi[sgsn_idx] & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002542 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002543 }
2544}
2545/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2546testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2547
2548 f_init();
2549 f_sleep(3.0);
2550
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002551 for (var integer i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
2552 g_roroi[i] := {};
2553 }
2554
Harald Welte16786e92020-11-27 19:11:56 +01002555 /* Start BVC-RESET procedure for BVCI=0 */
2556 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2557
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002558 /* Activate altsteps: One for each PTP BVC and SGSN within that PCUs NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002559 var ro_default defaults := {};
2560 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2561 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002562 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2563 var default d := activate(as_count_bvc_block(j, bvcc.bvci, g_roroi));
2564 defaults := defaults & { d };
2565 }
Harald Welte16786e92020-11-27 19:11:56 +01002566 }
2567
2568 timer T := 3.0;
2569 T.start;
2570 alt {
2571 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2572 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2573 }
2574 [] T.timeout;
2575 }
2576
2577 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2578 deactivate(defaults[i]);
2579 }
2580
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002581 /* check if BVC-block was received on all expected BVC/SGSN */
Harald Welte16786e92020-11-27 19:11:56 +01002582 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2583 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
Daniel Willmannc38c85d2021-01-21 18:11:12 +01002584 for (var integer j := 0; j < lengthof(g_sgsn); j := j+1) {
2585 if (not ro_integer_contains(g_roroi[j], bvcc.bvci)) {
2586 setverdict(fail, "Missing SGSN[", j, "] BVC-BLOCK of BVCI=", bvcc.bvci);
2587 }
Harald Welte16786e92020-11-27 19:11:56 +01002588 }
2589 }
2590
2591 /* check if BVC-block was not received on any unexpected BVC is not required as
2592 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002593 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002594 f_cleanup();
2595}
2596
Harald Welte60a8ec72020-11-25 17:12:53 +01002597private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2598{
2599 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2600 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2601 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2602 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2603 var default d;
2604
2605 SGSN_MGMT.clear;
2606 PCU_MGMT.clear;
2607
2608 /* block the PTP BVC from the PCU side */
2609 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2610 /* expect state on both PCU and SGSN side to change */
2611 d := activate(as_ignore_status(PCU_MGMT));
2612 interleave {
2613 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2614 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2615 }
2616 deactivate(d);
2617 setverdict(pass);
2618}
2619/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2620testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2621{
2622 f_init();
2623 f_sleep(3.0);
2624 f_reset_ptp_bvc_from_sgsn(0, 0);
2625 f_cleanup();
2626}
2627
Daniel Willmannef7015f2021-01-08 00:43:56 +01002628private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2629 [] pt.receive {repeat; }
2630}
2631
Harald Welte16786e92020-11-27 19:11:56 +01002632private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2633runs on test_CT {
2634 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2635 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2636 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002637 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002638 }
2639}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002640
Harald Welte16786e92020-11-27 19:11:56 +01002641/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2642testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2643
2644 f_init();
2645 f_sleep(3.0);
2646
Daniel Willmannef7015f2021-01-08 00:43:56 +01002647 SGSN_MGMT.clear;
2648 PCU_MGMT.clear;
2649
Harald Welte16786e92020-11-27 19:11:56 +01002650 /* Start BVC-RESET procedure for BVCI=0 */
2651 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2652
Daniel Willmannef7015f2021-01-08 00:43:56 +01002653 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2654 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2655 * the port and a different message sits at the front we wait forever and fail the test.
2656 */
2657 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2658
Harald Welte16786e92020-11-27 19:11:56 +01002659 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002660 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2661 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2662 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2663 defaults := defaults & { d };
2664 }
2665
2666 f_sleep(3.0);
2667
2668 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2669 deactivate(defaults[i]);
2670 }
2671
2672 /* check if BVC-block was received on all expected BVC */
2673 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2674 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2675 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2676 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2677 }
2678 }
2679
2680 /* check if BVC-block was not received on any unexpected BVC is not required as
2681 * such a message would basically run into 'no matching clause' */
2682
2683 f_cleanup();
2684}
2685
Harald Welte299aa482020-12-09 15:10:55 +01002686/***********************************************************************
2687 * FLOW-CONTROL-BVC procedure
2688 ***********************************************************************/
2689
2690private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2691 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2692runs on GlobalTest_CT {
2693 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2694 roi := roi & { sgsn_idx };
2695 if (ispresent(tx_reply)) {
2696 G_SGSN[sgsn_idx].send(tx_reply);
2697 }
Harald Welte5fb01742021-01-15 21:07:52 +01002698 repeat;
Harald Welte299aa482020-12-09 15:10:55 +01002699 }
2700}
2701/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2702testcase TC_fc_bvc() runs on GlobalTest_CT
2703{
2704 f_init();
2705 f_global_init_ptp();
2706
2707 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2708 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2709 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2710 var template (omit) PDU_BSSGP ack_tx :=
2711 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2712
2713 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2714 G_PCU[0].send(pdu_tx);
2715
2716 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2717 var ro_default defaults := {};
2718 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2719 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2720 defaults := defaults & { d };
2721 }
2722
2723 f_sleep(3.0);
2724
2725 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2726 deactivate(defaults[i]);
2727 }
2728
2729 /* check if BVC-block was received on all expected BVC */
2730 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2731 if (not ro_integer_contains(g_roi, i)) {
2732 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2733 }
2734 }
2735
2736 /* Expect ACK on PCU side */
2737 G_PCU[0].receive(ack_tx);
2738
2739 setverdict(pass);
2740
2741 f_cleanup();
2742}
2743
Harald Weltecc3894b2020-12-09 16:50:12 +01002744/***********************************************************************
2745 * FLOW-CONTROL-MS procedure
2746 ***********************************************************************/
2747
2748private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2749 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2750
2751 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2752 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2753 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2754 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2755
2756 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2757 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2758
2759 setverdict(pass);
2760}
2761/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2762testcase TC_fc_ms() runs on test_CT
2763{
Harald Weltecc3894b2020-12-09 16:50:12 +01002764 f_init();
Harald Welte2ecbca82021-01-16 11:23:09 +01002765 f_start_handlers(refers(f_TC_fc_ms), testcasename(), 21);
Harald Weltecc3894b2020-12-09 16:50:12 +01002766 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
Harald Weltecc3894b2020-12-09 16:50:12 +01002767 f_cleanup();
2768}
2769
Harald Welted6f89812021-01-16 18:57:49 +01002770/***********************************************************************
2771 * MS-REGISTRATION ENQUIRY procedure
2772 ***********************************************************************/
Harald Weltecc3894b2020-12-09 16:50:12 +01002773
Harald Welted6f89812021-01-16 18:57:49 +01002774private function f_TC_ms_reg_enq(charstring id) runs on BSSGP_ConnHdlr
2775{
2776 f_pcu2sgsn(ts_BSSGP_MS_REG_ENQ(g_pars.imsi), tr_BSSGP_MS_REG_ENQ(g_pars.imsi), use_sig := true);
2777 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);
2778}
2779testcase TC_ms_reg_enq() runs on test_CT
2780{
2781 f_init();
2782 f_start_handlers(refers(f_TC_ms_reg_enq), testcasename(), 22);
2783 f_cleanup();
2784}
Harald Welte299aa482020-12-09 15:10:55 +01002785
Harald Weltef86f1852021-01-16 21:56:17 +01002786/***********************************************************************
2787 * RIM (RAN Information Management)
2788 ***********************************************************************/
2789
2790/* Our tests here are rather synthetic, as they don't reflect normal message flows
2791 as they would be observed in a live network. However, for testing gbproxy, this shouldn't
2792 matter as gbproxy is not concerned with anything but the source / destination routing
2793 information */
2794
2795/* gbproxy must route all unknown RIM Routing Info (Cell Id) to the SGSN. We just define
2796 one here of which we know it is not used among the [simulated] PCUs */
2797const BssgpCellId cell_id_sgsn := {
2798 ra_id := {
2799 lai := {
2800 mcc_mnc := c_mcc_mnc,
2801 lac := 65534
2802 },
2803 rac := 0
2804 },
2805 cell_id := 65533
2806};
2807
2808/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on any of our SGSN (RIM can be routed anywhere) */
2809friend function f_rim_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2810 integer pcu_idx := 0) runs on GlobalTest_CT {
2811 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002812 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002813
2814 RIM_PCU[pcu_idx].send(tx);
2815 T.start;
2816 alt {
2817 [] any from RIM_SGSN.receive(exp_rx) {
2818 setverdict(pass);
2819 }
2820 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002821 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002822 }
2823 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002824 f_shutdown(__FILE__, __LINE__, fail,
2825 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002826 }
2827 }
2828}
2829
2830/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
2831friend function f_rim_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2832 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
2833 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002834 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002835
2836 RIM_SGSN[sgsn_idx].send(tx);
2837 T.start;
2838 alt {
2839 [] RIM_PCU[pcu_idx].receive(exp_rx) {
2840 setverdict(pass);
2841 }
2842 [] RIM_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002843 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on PCU side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002844 }
2845 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002846 f_shutdown(__FILE__, __LINE__, fail,
2847 log2str("Timeout waiting for BSSGP on PCU side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002848 }
2849 }
2850}
2851
2852/* Send 'tx' on PTP-BVCI from SRC-PCU; expect 'rx' on DST-PCU */
2853friend function f_rim_pcu2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
2854 integer src_pcu_idx, integer dst_pcu_idx) runs on GlobalTest_CT {
2855 var integer rx_idx;
2856 var PDU_BSSGP rx;
Harald Welte14d23ef2021-01-26 15:43:41 +01002857 timer T := 2.0;
Harald Weltef86f1852021-01-16 21:56:17 +01002858
2859 RIM_PCU[src_pcu_idx].send(tx);
2860 T.start;
2861 alt {
2862 [] RIM_PCU[dst_pcu_idx].receive(exp_rx) -> value rx{
2863 setverdict(pass);
2864 }
2865 [] any from RIM_PCU.receive(exp_rx) -> @index value rx_idx {
2866 setverdict(fail, "Received RIM on wrong PCU[", rx_idx ,"], expected on PCU[", dst_pcu_idx, "]");
2867 }
2868 [] any from RIM_SGSN.receive(exp_rx) {
2869 setverdict(fail, "Received RIM on SGSN but expected it on other PCU");
2870 }
2871 [] any from RIM_SGSN.receive(PDU_BSSGP:?) -> value rx {
Harald Welted5b7e742021-01-27 10:50:24 +01002872 f_shutdown(__FILE__, __LINE__, fail, log2str("Unexpected BSSGP on SGSN side: ", rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002873 }
2874 [] T.timeout {
Harald Welted5b7e742021-01-27 10:50:24 +01002875 f_shutdown(__FILE__, __LINE__, fail,
2876 log2str("Timeout waiting for BSSGP on SGSN side: ", exp_rx));
Harald Weltef86f1852021-01-16 21:56:17 +01002877 }
2878 }
2879}
2880
2881
2882type function rim_fn(integer sgsn_idx, integer pcu_idx, integer bvc_idx) runs on GlobalTest_CT;
2883
2884/* helper function for the RIM test cases: Execute 'fn' for each BVC on each PCU for
2885 each SGSN */
2886private function f_rim_iterator(rim_fn fn) runs on GlobalTest_CT
2887{
2888 var integer sgsn_idx, pcu_idx, bvc_idx;
2889 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx+1) {
2890 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx+1) {
2891 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx+1) {
2892 log("Testing RIM SGSN[", sgsn_idx, "] <-> PCU[", pcu_idx, "][", bvc_idx, "]");
2893 fn.apply(sgsn_idx, pcu_idx, bvc_idx);
2894 }
2895 }
2896 }
2897}
2898
2899/* RAN-INFORMATION-REQUEST */
2900private function f_TC_rim_info_req(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2901runs on GlobalTest_CT
2902{
2903 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2904 var template (value) RIM_Routing_Information ri_pcu;
2905 var template (value) RIM_Routing_Information ri_sgsn;
2906 var template (value) RAN_Information_Request_RIM_Container cont;
2907
2908 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2909 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2910 cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2911 ts_RIM_Sequence_Number(0),
2912 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2913 f_rim_pcu2sgsn(ts_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2914 tr_RAN_INFORMATION_REQUEST(dst := ri_sgsn, src := ri_pcu, cont := cont),
2915 pcu_idx);
2916 f_rim_sgsn2pcu(ts_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2917 tr_RAN_INFORMATION_REQUEST(dst := ri_pcu, src := ri_sgsn, cont := cont),
2918 sgsn_idx, pcu_idx);
2919}
2920testcase TC_rim_info_req() runs on GlobalTest_CT
2921{
2922 f_init();
2923 f_global_init();
2924 f_rim_iterator(refers(f_TC_rim_info_req));
2925 f_cleanup();
2926}
2927
2928/* RAN-INFORMATION */
2929private function f_TC_rim_info(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2930runs on GlobalTest_CT
2931{
2932 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2933 var template (value) RIM_Routing_Information ri_pcu;
2934 var template (value) RIM_Routing_Information ri_sgsn;
2935 var template (value) RAN_Information_RIM_Container cont;
2936
2937 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2938 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2939 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2940 ts_RIM_Sequence_Number(0),
2941 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
2942 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2943 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_sgsn, src := ri_pcu, cont := cont),
2944 pcu_idx);
2945 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2946 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu, src := ri_sgsn, cont := cont),
2947 sgsn_idx, pcu_idx);
2948}
2949testcase TC_rim_info() runs on GlobalTest_CT
2950{
2951 f_init();
2952 f_global_init();
2953 f_rim_iterator(refers(f_TC_rim_info));
2954 f_cleanup();
2955}
2956
2957/* RAN-INFORMATION-ACK */
2958private function f_TC_rim_info_ack(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2959runs on GlobalTest_CT
2960{
2961 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2962 var template (value) RIM_Routing_Information ri_pcu;
2963 var template (value) RIM_Routing_Information ri_sgsn;
2964 var template (value) RAN_Information_Ack_RIM_Container cont;
2965
2966 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2967 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2968 cont := ts_RAN_Information_Ack_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2969 ts_RIM_Sequence_Number(0));
2970 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2971 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_sgsn, src := ri_pcu, cont := cont),
2972 pcu_idx);
2973 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2974 tr_PDU_BSSGP_RAN_INFORMATION_ACK(dst := ri_pcu, src := ri_sgsn, cont := cont),
2975 sgsn_idx, pcu_idx);
2976}
2977testcase TC_rim_info_ack() runs on GlobalTest_CT
2978{
2979 f_init();
2980 f_global_init();
2981 f_rim_iterator(refers(f_TC_rim_info_ack));
2982 f_cleanup();
2983}
2984
2985/* RAN-INFORMATION-ERROR */
2986private function f_TC_rim_info_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
2987runs on GlobalTest_CT
2988{
2989 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
2990 var template (value) RIM_Routing_Information ri_pcu;
2991 var template (value) RIM_Routing_Information ri_sgsn;
2992 var template (value) RAN_Information_Error_RIM_Container cont;
2993
2994 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
2995 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
2996 cont := ts_RAN_Information_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
2997 ts_BSSGP_CAUSE(BSSGP_CAUSE_EQUIMENT_FAILURE),
2998 omit, valueof(t_BVC_UNBLOCK(23)));
2999 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3000 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3001 pcu_idx);
3002 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3003 tr_PDU_BSSGP_RAN_INFORMATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3004 sgsn_idx, pcu_idx);
3005}
3006testcase TC_rim_info_error() runs on GlobalTest_CT
3007{
3008 f_init();
3009 f_global_init();
3010 f_rim_iterator(refers(f_TC_rim_info_error));
3011 f_cleanup();
3012}
3013
3014/* RAN-INFORMATION-APPLICATION-ERROR */
3015private function f_TC_rim_info_app_error(integer sgsn_idx, integer pcu_idx, integer bvc_idx := 0)
3016runs on GlobalTest_CT
3017{
3018 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3019 var template (value) RIM_Routing_Information ri_pcu;
3020 var template (value) RIM_Routing_Information ri_sgsn;
3021 var template (value) Application_Error_Container app_cont;
3022 var template (value) RAN_Information_Application_Error_RIM_Container cont;
3023
3024 ri_sgsn := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id_sgsn));
3025 ri_pcu := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, t_RIM_Routing_Address_cid(cell_id));
3026 app_cont := tsu_Application_Error_Container_NACC(cell_id, 23,
3027 tsu_Application_Container_IE_NACC_req(cell_id));
3028 cont := ts_RAN_Information_Application_Error_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3029 ts_RIM_Sequence_Number(0),
3030 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP),
3031 omit, app_cont);
3032 f_rim_pcu2sgsn(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3033 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_sgsn, src := ri_pcu, cont := cont),
3034 pcu_idx);
3035 f_rim_sgsn2pcu(ts_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3036 tr_PDU_BSSGP_RAN_INFORMATION_APPLICATION_ERROR(dst := ri_pcu, src := ri_sgsn, cont := cont),
3037 sgsn_idx, pcu_idx);
3038}
3039testcase TC_rim_info_app_error() runs on GlobalTest_CT
3040{
3041 f_init();
3042 f_global_init();
3043 f_rim_iterator(refers(f_TC_rim_info_app_error));
3044 f_cleanup();
3045}
3046
3047/* RAN-INFORMATION routing directly between PCUs, without SGSN involvement */
3048private function f_TC_rim_info_pcu2pcu(integer src_pcu_idx, integer src_bvc_idx,
3049 integer dst_pcu_idx, integer dst_bvc_idx)
3050runs on GlobalTest_CT
3051{
3052 var BssgpCellId cell_id_src := g_pcu[src_pcu_idx].cfg.bvc[src_bvc_idx].cell_id;
3053 var BssgpCellId cell_id_dst := g_pcu[dst_pcu_idx].cfg.bvc[dst_bvc_idx].cell_id;
3054 var template (value) RIM_Routing_Information ri_pcu_src;
3055 var template (value) RIM_Routing_Information ri_pcu_dst;
3056 var template (value) RAN_Information_RIM_Container cont;
3057
3058 log("Testing RIM PCU2PCU from PCU[", src_pcu_idx, "][", src_bvc_idx, "] to PCU[",
3059 dst_pcu_idx, "][", dst_bvc_idx, "]");
3060
3061 ri_pcu_src := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3062 t_RIM_Routing_Address_cid(cell_id_src));
3063 ri_pcu_dst := ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID,
3064 t_RIM_Routing_Address_cid(cell_id_dst));
3065 cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3066 ts_RIM_Sequence_Number(0),
3067 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_STOP));
3068 f_rim_pcu2pcu(ts_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3069 tr_PDU_BSSGP_RAN_INFORMATION(dst := ri_pcu_dst, src := ri_pcu_src, cont := cont),
3070 src_pcu_idx, dst_pcu_idx);
3071}
3072testcase TC_rim_info_pcu2pcu() runs on GlobalTest_CT
3073{
3074 var integer src_pcu_idx, dst_pcu_idx;
3075 var integer src_bvc_idx, dst_bvc_idx;
3076 f_init();
3077 f_global_init();
3078
3079 for (src_pcu_idx := 0; src_pcu_idx < lengthof(g_pcu); src_pcu_idx := src_pcu_idx + 1) {
3080 for (src_bvc_idx := 0; src_bvc_idx < lengthof(g_pcu[src_pcu_idx].cfg.bvc); src_bvc_idx := src_bvc_idx + 1) {
3081 for (dst_pcu_idx := 0; dst_pcu_idx < lengthof(g_pcu); dst_pcu_idx := dst_pcu_idx + 1) {
3082 if (dst_pcu_idx == src_pcu_idx) {
3083 continue;
3084 }
3085
3086 for (dst_bvc_idx := 0; dst_bvc_idx < lengthof(g_pcu[dst_pcu_idx].cfg.bvc);
3087dst_bvc_idx := dst_bvc_idx + 1) {
3088 f_TC_rim_info_pcu2pcu(src_pcu_idx, src_bvc_idx, dst_pcu_idx, dst_bvc_idx);
3089 }
3090 }
3091 }
3092 }
3093
3094 f_cleanup();
3095}
3096
Harald Welte04358652021-01-17 13:48:13 +01003097/***********************************************************************
3098 * STATUS handling
3099 ***********************************************************************/
3100
3101/* BSSGP STATUS PDU must be routed based on inner "PDU In Error" message */
3102
3103/* generate a TMSI with NRI matching sgsn_idx + nri_idx */
3104private function f_gen_tmsi_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3105{
3106 var integer nri := mp_sgsn_nri[sgsn_idx][nri_idx];
3107 return f_gen_tmsi(0, nri_v := nri, nri_bitlen := mp_nri_bitlength);
3108}
3109
3110/* generate a TLLI with NRI matching sgsn_idx + nri_idx */
3111private function f_gen_tlli_for_sgsn_nri(integer sgsn_idx, integer nri_idx) runs on test_CT return OCT4
3112{
3113 var OCT4 p_tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3114 return f_gprs_tlli_from_tmsi(p_tmsi, TLLI_LOCAL);
3115}
3116
3117/* STATUS in uplink direction; expect routing by its NRI */
3118private function f_TC_status_ul(integer pcu_idx, integer sgsn_idx, PDU_BSSGP inner)
3119runs on GlobalTest_CT
3120{
3121 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3122 var template (present) PDU_BSSGP exp_rx :=
3123 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3124 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3125
3126 f_global_pcu2sgsn(tx, exp_rx, pcu_idx, sgsn_idx);
3127}
3128
3129/* STATUS in uplink direction; expect routing by its NRI */
3130private function f_TC_status_dl(integer sgsn_idx, integer pcu_idx, PDU_BSSGP inner)
3131runs on GlobalTest_CT
3132{
3133 var template (value) PDU_BSSGP tx := ts_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE, inner);
3134 var template (present) PDU_BSSGP exp_rx :=
3135 tr_BSSGP_STATUS(omit, BSSGP_CAUSE_EQUIMENT_FAILURE,
3136 tx.pDU_BSSGP_STATUS.pDU_in_Error.erroneous_BSSGP_PDU);
3137
3138 f_global_sgsn2pcu(tx, exp_rx, sgsn_idx, pcu_idx);
3139}
3140
3141/* STATUS in uplink direction on SIG-BVC containing a TLLI; expect routing by its NRI */
3142testcase TC_status_sig_ul_tlli() runs on GlobalTest_CT
3143{
3144 var integer sgsn_idx, nri_idx;
3145
3146 f_init();
3147 f_global_init();
3148
3149 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3150 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3151 /* some downlink PDU occurring on SIG-BVC with a TLLI */
3152 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3153 var PDU_BSSGP inner := valueof(ts_BSSGP_FLUSH_LL(tlli, 2342));
3154
3155 f_TC_status_ul(0, sgsn_idx, inner);
3156 }
3157 }
3158
3159 f_cleanup();
3160}
3161
3162/* STATUS in uplink direction on SIG-BVC containing a TMSI; expect routing by its NRI */
3163testcase TC_status_sig_ul_tmsi() runs on GlobalTest_CT
3164{
3165 var integer sgsn_idx, nri_idx;
3166
3167 f_init();
3168 f_global_init();
3169
3170 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3171 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3172 /* some downlink PDU occurring on SIG-BVC with a TMSI */
3173 const hexstring imsi := '001010123456789'H
3174 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3175 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3176 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3177 f_TC_status_ul(0, sgsn_idx, inner);
3178 }
3179 }
3180
3181 f_cleanup();
3182}
3183
3184
3185/* STATUS in uplink direction on PTP-BVC containing a TLLI; expect routing by its NRI */
3186testcase TC_status_ptp_ul_tlli() runs on GlobalTest_CT
3187{
3188 var integer sgsn_idx, nri_idx;
3189
3190 f_init();
3191 f_global_init_ptp();
3192
3193 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3194 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3195 /* some downlink PDU occurring on PTP-BVC with a TLLI */
3196 var OCT4 tlli := f_gen_tlli_for_sgsn_nri(sgsn_idx, nri_idx);
3197 var PDU_BSSGP inner := valueof(ts_BSSGP_DL_UD(tlli, '2342'O));
3198
3199 f_TC_status_ul(0, sgsn_idx, inner);
3200 }
3201 }
3202
3203 f_cleanup();
3204}
3205
3206/* STATUS in uplink direction on PTP-BVC containing a TMSI; expect routing by its NRI */
3207testcase TC_status_ptp_ul_tmsi() runs on GlobalTest_CT
3208{
3209 var integer sgsn_idx, nri_idx;
3210
3211 f_init();
3212 f_global_init_ptp();
3213
3214 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3215 for (nri_idx := 0; nri_idx < lengthof(mp_sgsn_nri[sgsn_idx]); nri_idx := nri_idx + 1) {
3216 /* some downlink PDU occurring on PTP-BVC with a TMSI */
3217 const hexstring imsi := '001010123456789'H
3218 var OCT4 tmsi := f_gen_tmsi_for_sgsn_nri(sgsn_idx, nri_idx);
3219 var BssgpBvci bvci := g_pcu[0].cfg.bvc[0].bvci;
3220 var PDU_BSSGP inner := valueof(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3221 f_TC_status_ul(0, sgsn_idx, inner);
3222 }
3223 }
3224
3225 f_cleanup();
3226}
3227
3228/* STATUS in downlink direction in SIG-BVC containing a BVCI; expect routing by it */
3229testcase TC_status_sig_dl_bvci() runs on GlobalTest_CT
3230{
3231 var integer sgsn_idx, pcu_idx, bvc_idx;
3232
3233 f_init();
3234 f_global_init();
3235
3236 /* test each BVC in each PCU from each SGSN */
3237 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3238 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3239 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3240 /* some uplink PDU occurring on SIG-BVC containing a BVCI */
3241 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3242 var PDU_BSSGP inner := valueof(ts_BSSGP_LLC_DISCARDED('12345678'O, 1, bvci, 23));
3243 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3244 }
3245 }
3246 }
3247
3248 f_cleanup();
3249}
3250
3251/* STATUS in downlink direction in PTP-BVC; expect routing by BVCI */
3252testcase TC_status_ptp_dl_bvci() runs on GlobalTest_CT
3253{
3254 var integer sgsn_idx, pcu_idx, bvc_idx;
3255
3256 f_init();
3257 f_global_init_ptp();
3258
3259 /* test each BVC in each PCU from each SGSN */
3260 for (pcu_idx := 0; pcu_idx < lengthof(g_pcu); pcu_idx := pcu_idx + 1) {
3261 for (bvc_idx := 0; bvc_idx < lengthof(g_pcu[pcu_idx].cfg.bvc); bvc_idx := bvc_idx + 1) {
3262 var BssgpBvci bvci := g_pcu[pcu_idx].cfg.bvc[bvc_idx].bvci;
3263 f_global_ptp_connect_pcu_bvci(pcu_idx, bvci);
3264 for (sgsn_idx := 0; sgsn_idx < NUM_SGSN; sgsn_idx := sgsn_idx + 1) {
3265 f_global_ptp_connect_sgsn_bvci(sgsn_idx, bvci);
3266
3267 /* some uplink PDU occurring on PTP-BVC */
3268 var BssgpCellId cell_id := g_pcu[pcu_idx].cfg.bvc[bvc_idx].cell_id;
3269 var PDU_BSSGP inner := valueof(ts_BSSGP_UL_UD('12345678'O, cell_id, '4223'O));
3270 f_TC_status_dl(sgsn_idx, pcu_idx, inner);
3271 }
3272 }
3273 }
3274
3275 f_cleanup();
3276}
3277
3278/* TODO: test case for DL-STATUS(SUSPEND/RESUME) containing RA-ID; expect routing by RA-ID */
3279/* 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 +01003280
Daniel Willmann423d8f42020-09-08 18:58:22 +02003281control {
3282 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01003283 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01003284 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01003285 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01003286 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01003287 execute( TC_radio_status() );
Harald Welte3148a962021-01-17 11:15:28 +01003288 execute( TC_radio_status_tmsi() );
3289 execute( TC_radio_status_imsi() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01003290 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01003291 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01003292 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01003293 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01003294 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01003295 execute( TC_bvc_block_ptp() );
3296 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003297 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01003298 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01003299 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01003300 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01003301 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01003302 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
3303 execute( TC_load_sharing_dl() );
3304 }
Harald Welte0e188242020-11-22 21:46:48 +01003305
3306 /* PAGING-PS over PTP BVC */
3307 execute( TC_paging_ps_ptp_bss() );
3308 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003309 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003310 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003311 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003312 execute( TC_paging_ps_ptp_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003313 execute( TC_paging_ps_ptp_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003314 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003315 execute( TC_paging_ps_reject_ptp_bvci() );
3316 execute( TC_paging_ps_reject_ptp_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003317 execute( TC_dummy_paging_ps_ptp() );
Harald Welte0e188242020-11-22 21:46:48 +01003318
3319 /* PAGING-PS over SIG BVC */
3320 execute( TC_paging_ps_sig_bss() );
3321 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003322 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003323 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003324 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003325 execute( TC_paging_ps_sig_bvci() );
Harald Welteb5a04aa2021-01-16 13:04:40 +01003326 execute( TC_paging_ps_sig_bvci_imsi() );
Harald Welte7462a592020-11-23 22:07:07 +01003327 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Weltecf200072021-01-16 15:20:46 +01003328 execute( TC_paging_ps_reject_sig_bvci() );
3329 execute( TC_paging_ps_reject_sig_bvci_imsi() );
Harald Welte7595d562021-01-16 19:09:20 +01003330 execute( TC_dummy_paging_ps_sig() );
Harald Welte0e188242020-11-22 21:46:48 +01003331
3332 /* PAGING-CS over PTP BVC */
3333 execute( TC_paging_cs_ptp_bss() );
3334 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003335 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003336 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003337 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003338 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003339 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003340
3341 /* PAGING-CS over SIG BVC */
3342 execute( TC_paging_cs_sig_bss() );
3343 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01003344 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003345 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01003346 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003347 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01003348 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01003349
Harald Weltef86f1852021-01-16 21:56:17 +01003350 /* RAN Information Management */
3351 execute( TC_rim_info_req() );
3352 execute( TC_rim_info() );
3353 execute( TC_rim_info_ack() );
3354 execute( TC_rim_info_error() );
3355 execute( TC_rim_info_app_error() );
3356 execute( TC_rim_info_pcu2pcu() );
3357
Harald Welte0e188242020-11-22 21:46:48 +01003358
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01003359 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01003360 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01003361 execute( TC_fc_ms() );
Harald Welted6f89812021-01-16 18:57:49 +01003362 execute( TC_ms_reg_enq() );
Harald Welte04358652021-01-17 13:48:13 +01003363
3364 /* Uplink STATUS */
3365 execute( TC_status_sig_ul_tlli() );
3366 execute( TC_status_sig_ul_tmsi() );
3367 execute( TC_status_ptp_ul_tlli() );
3368 execute( TC_status_ptp_ul_tmsi() );
3369
3370 /* Downlink STATUS */
3371 execute( TC_status_sig_dl_bvci() );
3372 execute( TC_status_ptp_dl_bvci() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02003373}
3374
3375
3376}