blob: 2797a2ca982e5fa03e1e1869f9d2a8e0abf1f00b [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
17import from GSM_Types all;
18import from Native_Functions all;
19import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
23import from SCCPasp_Types all;
24import from Osmocom_Gb_Types all;
25
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from TELNETasp_PortType all;
33import from Osmocom_VTY_Functions all;
34
35import from LLC_Types all;
36import from LLC_Templates all;
37
38import from GSM_RR_Types all;
39
Harald Welte6d63f742020-11-15 19:44:04 +010040/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
41const BcdMccMnc c_mcc_mnc := '262F42'H;
42
Harald Welte0d5fceb2020-11-29 16:04:07 +010043/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
44const integer max_fr_info_size := 1600;
45
Daniel Willmann423d8f42020-09-08 18:58:22 +020046modulepar {
47 /* IP/port on which we run our internal GSUP/HLR emulation */
Harald Welte6d63f742020-11-15 19:44:04 +010048 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020049 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020050 nsei := 101,
51 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010052 handle_sns := false,
53 nsvc := {
54 {
55 provider := {
56 ip := {
57 address_family := AF_INET,
58 local_udp_port := 7777,
59 local_ip := "127.0.0.1",
60 remote_udp_port := 23000,
61 remote_ip := "127.0.0.1"
62 }
63 },
64 nsvci := 101
65 }
66 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020067 }
68 };
Harald Welte6d63f742020-11-15 19:44:04 +010069 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020070 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020071 nsei := 96,
72 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010073 handle_sns := false,
74 nsvc := {
75 {
76 provider := {
77 ip := {
78 address_family := AF_INET,
79 local_udp_port := 21010,
80 local_ip := "127.0.0.1",
81 remote_udp_port := 23000,
82 remote_ip := "127.0.0.1"
83 }
84 },
85 nsvci := 97
86 }
87 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020088 },
89 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020090 nsei := 97,
91 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010092 handle_sns := false,
93 nsvc := {
94 {
95 provider := {
96 ip := {
97 address_family := AF_INET,
98 local_udp_port := 21011,
99 local_ip := "127.0.0.1",
100 remote_udp_port := 23000,
101 remote_ip := "127.0.0.1"
102 }
103 },
104 nsvci := 98
105 }
106 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200107 },
108 {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200109 nsei := 98,
110 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100111 handle_sns := false,
112 nsvc := {
113 {
114 provider := {
115 ip := {
116 address_family := AF_INET,
117 local_udp_port := 21012,
118 local_ip := "127.0.0.1",
119 remote_udp_port := 23000,
120 remote_ip := "127.0.0.1"
121 }
122 },
123 nsvci := 99
124 }
125 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200126 }
127 };
Harald Welte6d63f742020-11-15 19:44:04 +0100128 BssgpConfigs mp_gbconfigs := {
129 {
130 nsei := 96,
131 sgsn_role := false,
132 bvc := {
133 {
134 bvci := 196,
135 cell_id := {
136 ra_id := {
137 lai := {
138 mcc_mnc := c_mcc_mnc,
139 lac := 13135
140 },
141 rac := 0
142 },
143 cell_id := 20960
144 },
145 depth := BSSGP_DECODE_DEPTH_BSSGP,
146 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
147 }
148 }
149 }, {
150 nsei := 97,
151 sgsn_role := false,
152 bvc := {
153 {
154 bvci := 210,
155 cell_id := {
156 ra_id := {
157 lai := {
158 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100159 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100160 },
Harald Welte0e188242020-11-22 21:46:48 +0100161 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100162 },
163 cell_id := 20961
164 },
165 depth := BSSGP_DECODE_DEPTH_BSSGP,
166 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
167 }
168 }
169 }, {
170 nsei := 98,
171 sgsn_role := false,
172 bvc := {
173 {
174 bvci := 220,
175 cell_id := {
176 ra_id := {
177 lai := {
178 mcc_mnc := c_mcc_mnc,
179 lac := 13300
180 },
181 rac := 0
182 },
183 cell_id := 20962
184 },
185 depth := BSSGP_DECODE_DEPTH_BSSGP,
186 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
187 }
188 }
189 }
190 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200191};
192
Daniel Willmann423d8f42020-09-08 18:58:22 +0200193type record GbInstance {
194 NS_CT vc_NS,
195 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100196 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200197 BssgpConfig cfg
198};
Harald Welte67dc8c22020-11-17 18:32:29 +0100199type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200200
201const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100202type record of GbInstance GbInstances;
203type record of BssgpConfig BssgpConfigs;
204type record of NSConfiguration NSConfigurations;
205type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200206
207const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200208
209type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100210 var GbInstances g_pcu;
211 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200212
213 port BSSGP_CT_PROC_PT PROC;
214
Harald Weltefbae83f2020-11-15 23:25:55 +0100215 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
216 port BSSGP_BVC_MGMT_PT PCU_MGMT;
217
Daniel Willmann423d8f42020-09-08 18:58:22 +0200218 port TELNETasp_PT GBPVTY;
219
220 var boolean g_initialized := false;
221 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100222
223 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200224};
225
226type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100227 /* array of per-BVC ports on the PCU side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200228 port BSSGP_PT PCU[NUM_PCU];
229 port BSSGP_PT PCU_SIG[NUM_PCU];
230 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100231 /* component reference to the component to which we're currently connected */
232 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100233 /* BSSGP BVC configuration of the component to which we're currently connected */
234 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100235
236 /* array of per-BVC ports on the SGSN side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200237 port BSSGP_PT SGSN[NUM_SGSN];
238 port BSSGP_PT SGSN_SIG[NUM_SGSN];
239 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100240 /* component reference to the component to which we're currently connected */
241 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200242
243 var BSSGP_ConnHdlrPars g_pars;
244 timer g_Tguard;
245 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100246
247 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200248}
249
250type record SGSN_ConnHdlrNetworkPars {
251 boolean expect_ptmsi,
252 boolean expect_auth,
253 boolean expect_ciph
254};
255
256type record BSSGP_ConnHdlrPars {
257 /* IMEI of the simulated ME */
258 hexstring imei,
259 /* IMSI of the simulated MS */
260 hexstring imsi,
261 /* MSISDN of the simulated MS (probably unused) */
262 hexstring msisdn,
263 /* P-TMSI allocated to the simulated MS */
264 OCT4 p_tmsi optional,
265 OCT3 p_tmsi_sig optional,
266 /* TLLI of the simulated MS */
267 OCT4 tlli,
268 OCT4 tlli_old optional,
269 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100270 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100271 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200272 float t_guard
273};
274
275private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
276 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
277 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
278
279 var RoutingAreaIdentificationV ret := {
280 mccDigit1 := mcc_mnc[0],
281 mccDigit2 := mcc_mnc[1],
282 mccDigit3 := mcc_mnc[2],
283 mncDigit3 := mcc_mnc[3],
284 mncDigit1 := mcc_mnc[4],
285 mncDigit2 := mcc_mnc[5],
286 lac := int2oct(cell_id.ra_id.lai.lac, 16),
287 rac := int2oct(cell_id.ra_id.rac, 8)
288 }
289 return ret;
290};
291
292private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100293 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
294 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
295 gb.vc_NS := NS_CT.create(ns_id);
296 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200297 /* connect lower end of BSSGP emulation with NS upper port */
298 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
299
Harald Welteb419d0e2020-11-16 16:45:05 +0100300 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
301 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302
303 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
304 connect(self:PROC, gb.vc_BSSGP:PROC);
305 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
306 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100307 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200308 }
Harald Welte16786e92020-11-27 19:11:56 +0100309 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200310}
311
312private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100313 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
314 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
315 gb.vc_NS := NS_CT.create(ns_id);
316 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200317 /* connect lower end of BSSGP emulation with NS upper port */
318 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
319
Harald Welteb419d0e2020-11-16 16:45:05 +0100320 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
321 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200322
323 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
324 connect(self:PROC, gb.vc_BSSGP:PROC);
325 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
326 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100327 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200328 }
Harald Welte16786e92020-11-27 19:11:56 +0100329 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200330}
331
332
333private function f_init_vty() runs on test_CT {
334 map(self:GBPVTY, system:GBPVTY);
335 f_vty_set_prompts(GBPVTY);
336 f_vty_transceive(GBPVTY, "enable");
337}
338
Harald Weltefbae83f2020-11-15 23:25:55 +0100339type record of integer ro_integer;
340
341private function ro_integer_contains(ro_integer r, integer x) return boolean {
342 for (var integer j := 0; j < lengthof(r); j := j+1) {
343 if (r[j] == x) {
344 return true;
345 }
346 }
347 return false;
348}
349
Harald Welte6d63f742020-11-15 19:44:04 +0100350function f_init() runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100351 var ro_integer bvci_unblocked := {};
352 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200353 var integer i;
354
355 if (g_initialized == true) {
356 return;
357 }
358 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200359
360 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100361 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200362 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100363 bvc := { }
364 }
365 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
366 g_pcu[i].cfg := mp_gbconfigs[i];
367 /* concatenate all the PCU-side BVCs for the SGSN side */
368 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & mp_gbconfigs[i].bvc;
369 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200370
371 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100372 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100373 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Harald Welteea1ba592020-11-17 18:05:13 +0100374 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100375 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200376 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100377 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100378 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100379 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100380
381 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100382 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100383 T.start;
384 alt {
385 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
386 bvci_unblocked := bvci_unblocked & { bsi.bvci };
387 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
388 repeat;
389 }
390 }
391 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
392 repeat;
393 }
Harald Welte3c905152020-11-26 20:56:09 +0100394 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
395 repeat;
396 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100397 [] SGSN_MGMT.receive {
398 setverdict(fail, "Received unexpected message on SGSN_MGMT");
399 mtc.stop;
400 }
401
402 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
403 repeat;
404 }
405 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
406 repeat;
407 }
408 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
409 repeat;
410 }
411 [] PCU_MGMT.receive {
412 setverdict(fail, "Received unexpected message on PCU_MGMT");
413 mtc.stop;
414 }
415
416 [] T.timeout {
417 setverdict(fail, "Timeout waiting for unblock of all BVCs");
418 mtc.stop;
419 }
420 }
421
422 /* iterate over list and check all BVCI */
423 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
424 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
425 if (not ro_integer_contains(bvci_unblocked, bvci)) {
426 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
427 mtc.stop;
428 }
429 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200430}
431
432function f_cleanup() runs on test_CT {
433 self.stop;
434}
435
436type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
437
438/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100439function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200440 float t_guard := 30.0)
441runs on test_CT return BSSGP_ConnHdlr {
442 var BSSGP_ConnHdlr vc_conn;
443
444 var BSSGP_ConnHdlrPars pars := {
445 imei := f_gen_imei(imsi_suffix),
446 imsi := f_gen_imsi(imsi_suffix),
447 msisdn := f_gen_msisdn(imsi_suffix),
448 p_tmsi := omit,
449 p_tmsi_sig := omit,
450 tlli := f_gprs_tlli_random(),
451 tlli_old := omit,
452 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100453 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100454 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200455 t_guard := t_guard
456 };
457
458 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200459
460 vc_conn.start(f_handler_init(fn, id, pars));
461 return vc_conn;
462}
463
Harald Welte3dd21b32020-11-17 19:21:00 +0100464/* 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 +0100465private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
466runs on BSSGP_ConnHdlr {
467 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100468 if (PCU[port_idx].checkstate("Connected")) {
469 /* unregister + disconnect from old BVC */
470 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
471 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
472 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
473 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
474 }
475 /* connect to new BVC and register us */
476 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
477 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
478 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
479 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
480 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100481 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100482}
483
484/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
485private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
486 if (SGSN[port_idx].checkstate("Connected")) {
487 /* unregister + disconnect from old BVC */
488 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
489 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
490 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
491 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
492 }
493 /* connect to new BVC and register us */
494 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
495 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
496 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
497 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
498 sgsn_ct[port_idx] := bvc_ct;
499}
500
Daniel Willmann423d8f42020-09-08 18:58:22 +0200501private altstep as_Tguard() runs on BSSGP_ConnHdlr {
502 [] g_Tguard.timeout {
503 setverdict(fail, "Tguard timeout");
504 mtc.stop;
505 }
506}
507
508/* first function called in every ConnHdlr */
509private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
510runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100511 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200512 /* do some common stuff like setting up g_pars */
513 g_pars := pars;
514
515 llc := f_llc_create(false);
516
Harald Welte3dd21b32020-11-17 19:21:00 +0100517 /* default connections on PCU side: First BVC of each NSE/PCU */
518 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100519 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100520 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100521
522 /* default connections on SGSN side: First BVC of each NSE/SGSN */
523 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
524 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100525 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200526
527 g_Tguard.start(pars.t_guard);
528 activate(as_Tguard());
529
530 /* call the user-supplied test case function */
531 fn.apply(id);
532}
533
Harald Welte1e834f32020-11-15 20:02:59 +0100534private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
535runs on BSSGP_ConnHdlr {
536 PT.call(BSSGP_register_client:{imsi, tlli}) {
537 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
538 }
539}
540
541private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
542runs on BSSGP_ConnHdlr {
543 PT.call(BSSGP_unregister_client:{imsi}) {
544 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
545 }
546}
547
Harald Welte22ef5d92020-11-16 13:35:14 +0100548/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
549friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100550 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100551 var PDU_BSSGP rx;
552 timer T := 1.0;
553
Daniel Willmann4798fd72020-11-24 16:23:29 +0100554 if (use_sig) {
555 PCU_SIG[pcu_idx].send(tx);
556 } else {
557 PCU[pcu_idx].send(tx);
558 }
559
Harald Welte22ef5d92020-11-16 13:35:14 +0100560 T.start;
561 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100562 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
563 setverdict(pass);
564 }
565 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100566 setverdict(pass);
567 }
568 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
569 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
570 mtc.stop;
571 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100572 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
573 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
574 mtc.stop;
575 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100576 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100577 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100578 mtc.stop;
579 }
580 }
581}
582
583/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
584friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100585 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100586 var PDU_BSSGP rx;
587 timer T := 1.0;
588
Daniel Willmann4798fd72020-11-24 16:23:29 +0100589 if (use_sig) {
590 SGSN_SIG[sgsn_idx].send(tx);
591 } else {
592 SGSN[sgsn_idx].send(tx);
593 }
594
Harald Welte22ef5d92020-11-16 13:35:14 +0100595 T.start;
596 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100597 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
598 setverdict(pass);
599 }
600 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100601 setverdict(pass);
602 }
603 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
604 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
605 mtc.stop;
606 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100607 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
608 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
609 mtc.stop;
610 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100611 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100612 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100613 mtc.stop;
614 }
615 }
616}
Harald Welte1e834f32020-11-15 20:02:59 +0100617
Harald Welte3807ed12020-11-24 19:05:22 +0100618/***********************************************************************
619 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
620 ***********************************************************************/
621
622type component GlobalTest_CT extends test_CT {
623 port BSSGP_PT G_PCU[NUM_PCU];
624 port BSSGP_PT G_SGSN[NUM_SGSN];
625};
626
627private function f_global_init() runs on GlobalTest_CT {
628 var integer i;
629 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
630 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
631 }
632 for (i := 0; i < lengthof(g_pcu); i := i+1) {
633 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
634 }
635}
636
637/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
638friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
639 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
640 var PDU_BSSGP rx;
641 timer T := 1.0;
642
643 G_PCU[pcu_idx].send(tx);
644 T.start;
645 alt {
646 [] G_SGSN[sgsn_idx].receive(exp_rx) {
647 setverdict(pass);
648 }
649 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
650 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
651 mtc.stop;
652 }
653 [] T.timeout {
654 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
655 mtc.stop;
656 }
657 }
658}
659
660/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
661friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
662 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
663 var PDU_BSSGP rx;
664 timer T := 1.0;
665
666 G_SGSN[sgsn_idx].send(tx);
667 T.start;
668 alt {
669 [] G_PCU[pcu_idx].receive(exp_rx) {
670 setverdict(pass);
671 }
672 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
673 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
674 mtc.stop;
675 }
676 [] T.timeout {
677 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
678 mtc.stop;
679 }
680 }
681}
682
683
Daniel Willmann423d8f42020-09-08 18:58:22 +0200684/* TODO:
685 * Detach without Attach
686 * SM procedures without attach / RAU
687 * ATTACH / RAU
688 ** with / without authentication
689 ** with / without P-TMSI allocation
690 * re-transmissions of LLC frames
691 * PDP Context activation
692 ** with different GGSN config in SGSN VTY
693 ** with different PDP context type (v4/v6/v46)
694 ** timeout from GGSN
695 ** multiple / secondary PDP context
696 */
697
698private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
699 f_sleep(5.0);
700 setverdict(pass);
701}
702
703testcase TC_BVC_bringup() runs on test_CT {
704 var BSSGP_ConnHdlr vc_conn;
705 f_init();
706
707 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
708 vc_conn.done;
709
710 f_cleanup();
711}
712
713friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100714 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200715 timer T := 5.0;
716 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100717 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200718 T.start;
719 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100720 [] 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 +0200721 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
722 }
Harald Welte16357a92020-11-17 18:20:00 +0100723 [] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200724 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
725 mtc.stop;
726 }
727 [] T.timeout {
728 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
729 mtc.stop;
730 }
731 }
732 return '00'O;
733}
734
735friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100736 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200737 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100738 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 +0200739 T.start;
740 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100741 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
742 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200743 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
744 mtc.stop;
745 }
746 [] T.timeout {
747 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
748 mtc.stop;
749 }
750 }
751}
752
753
Harald Welte92686012020-11-15 21:45:49 +0100754/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
755private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100756 var integer ran_idx := 0;
757 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100758 var integer i;
759
Harald Welte0d5fceb2020-11-29 16:04:07 +0100760 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100761 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100762 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 +0100763 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100764 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 +0100765
Harald Welte0d5fceb2020-11-29 16:04:07 +0100766 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100767 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100768 }
769 setverdict(pass);
770}
771
772testcase TC_ul_unitdata() runs on test_CT
773{
774 var BSSGP_ConnHdlr vc_conn;
775 f_init();
776
777 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
778 vc_conn.done;
779 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
780
781 f_cleanup();
782}
783
Harald Welte78d8db92020-11-15 23:27:27 +0100784/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
785private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
786 var integer i;
787
Harald Welte0d5fceb2020-11-29 16:04:07 +0100788 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100789 var octetstring payload := f_rnd_octstring(i);
790 var template (value) PDU_BSSGP pdu_tx :=
791 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
792 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
793 var template (present) PDU_BSSGP pdu_rx :=
794 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
795
Harald Welte0d5fceb2020-11-29 16:04:07 +0100796 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100797 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100798 }
799 setverdict(pass);
800}
801
802testcase TC_dl_unitdata() runs on test_CT
803{
804 var BSSGP_ConnHdlr vc_conn;
805 f_init();
806
807 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
808 vc_conn.done;
809 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
810
811 f_cleanup();
812}
Harald Welte92686012020-11-15 21:45:49 +0100813
Harald Welte6dc2ac42020-11-16 09:16:17 +0100814private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
815 var integer i;
816
817 for (i := 0; i < 10; i := i+1) {
818 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
819 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
820 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
821
Harald Welte22ef5d92020-11-16 13:35:14 +0100822 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100823 }
824 setverdict(pass);
825}
826testcase TC_ra_capability() runs on test_CT
827{
828 var BSSGP_ConnHdlr vc_conn;
829 f_init();
830
831 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
832 vc_conn.done;
833 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
834
835 f_cleanup();
836}
837
Daniel Willmannace3ece2020-11-16 19:53:26 +0100838private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
839 var integer i;
840 var OCT1 tag;
841 for (i := 0; i < 10; i := i+1) {
842 tag := int2oct(23 + i, 1);
843 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
844 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
845 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
846
847 f_pcu2sgsn(pdu_tx, pdu_rx);
848
849 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
850 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
851 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
852
853 f_sgsn2pcu(pdu_tx, pdu_rx);
854 }
855 setverdict(pass);
856}
857testcase TC_ra_capability_upd() runs on test_CT
858{
859 var BSSGP_ConnHdlr vc_conn;
860 f_init();
861
Daniel Willmann54833f22020-11-19 15:43:52 +0100862 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100863 vc_conn.done;
864 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
865
866 f_cleanup();
867}
868
Daniel Willmann165d6612020-11-19 14:27:29 +0100869private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
870 var integer i;
871 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
872 for (i := 0; i < 10; i := i+1) {
873 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
874 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
875 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
876
877 f_pcu2sgsn(pdu_tx, pdu_rx);
878 }
879 setverdict(pass);
880}
881testcase TC_radio_status() runs on test_CT
882{
883 var BSSGP_ConnHdlr vc_conn;
884 f_init();
885
Daniel Willmann54833f22020-11-19 15:43:52 +0100886 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100887 vc_conn.done;
888 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
889
890 f_cleanup();
891}
892
Harald Welte3807ed12020-11-24 19:05:22 +0100893private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100894 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100895
Daniel Willmannfa67f492020-11-19 15:48:05 +0100896 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100897 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100898 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100899 var OCT4 tlli := f_gprs_tlli_random();
900 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100901 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100902 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100903
Harald Welte3807ed12020-11-24 19:05:22 +0100904 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100905
Harald Welte3807ed12020-11-24 19:05:22 +0100906 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100907 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100908 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100909
Harald Welte3807ed12020-11-24 19:05:22 +0100910 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100911
912 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100913 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100914 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100915 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100916
Harald Welte3807ed12020-11-24 19:05:22 +0100917 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100918 }
919 setverdict(pass);
920}
Harald Welte3807ed12020-11-24 19:05:22 +0100921testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100922{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100923 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100924 f_global_init();
925 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +0100926 f_cleanup();
927}
Harald Welte6dc2ac42020-11-16 09:16:17 +0100928
Harald Welte3807ed12020-11-24 19:05:22 +0100929private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +0100930 var integer i;
931
932 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100933 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +0100934 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100935 var OCT4 tlli := f_gprs_tlli_random();
936 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100937 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100938 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100939
Harald Welte3807ed12020-11-24 19:05:22 +0100940 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100941
Harald Welte3807ed12020-11-24 19:05:22 +0100942 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100943 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100944 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100945
Harald Welte3807ed12020-11-24 19:05:22 +0100946 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100947
948 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100949 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100950 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100951 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100952
Harald Welte3807ed12020-11-24 19:05:22 +0100953 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100954 }
955 setverdict(pass);
956}
Harald Welte3807ed12020-11-24 19:05:22 +0100957testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +0100958{
Daniel Willmann087a33d2020-11-19 15:58:43 +0100959 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100960 f_global_init();
961 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +0100962 f_cleanup();
963}
964
Harald Weltef8ef0282020-11-18 12:16:59 +0100965/* test the load-sharing between multiple NS-VC on the BSS side */
966private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
967 var integer i;
968
969 for (i := 0; i < 10; i := i+1) {
970 var octetstring payload := f_rnd_octstring(i);
971 var template (value) PDU_BSSGP pdu_tx :=
972 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
973 SGSN[0].send(pdu_tx);
974 }
975 setverdict(pass);
976}
977testcase TC_load_sharing_dl() runs on test_CT_NS
978{
979 const integer num_ue := 10;
980 var BSSGP_ConnHdlr vc_conn[num_ue];
981 f_init();
982
983 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
984 * side so we get the raw NsUnitdataIndication and hence observe different
985 * NSVCI */
986 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
987 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
988
989 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
990 * of the NS-VC is ALIVE/UNBLOCKED */
991 f_sleep(3.0);
992
993 /* start parallel components generating DL-UNITDATA from the SGSN side */
994 for (var integer i:= 0; i < num_ue; i := i+1) {
995 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
996 }
997
998 /* now start counting all the messages that were queued before */
999 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1000 var ro_integer rx_count := { 0, 0, 0, 0 };
1001 timer T := 2.0;
1002 T.start;
1003 alt {
1004 [] as_NsUdiCount(0, rx_count);
1005 [] as_NsUdiCount(1, rx_count);
1006 [] as_NsUdiCount(2, rx_count);
1007 [] as_NsUdiCount(3, rx_count);
1008 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1009 [] NS.receive(NsStatusIndication:?) { repeat; }
1010 [] NS.receive {
1011 setverdict(fail, "Rx unexpected NS");
1012 mtc.stop;
1013 }
1014 [] T.timeout {
1015 }
1016 }
1017 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1018 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1019 if (rx_count[i] == 0) {
1020 setverdict(fail, "Data not shared over all NSVC");
1021 }
1022 }
1023 setverdict(pass);
1024}
1025private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1026 var NsUnitdataIndication udi;
1027 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1028 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1029 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1030 repeat;
1031 }
1032}
1033type component test_CT_NS extends test_CT {
1034 port NS_PT NS;
1035};
1036
1037
Harald Welte0e188242020-11-22 21:46:48 +01001038/***********************************************************************
1039 * PAGING PS procedure
1040 ***********************************************************************/
1041
1042private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1043 boolean use_sig := false)
1044runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1045 var template (value) PDU_BSSGP pdu_tx;
1046 var template (present) PDU_BSSGP pdu_rx;
1047 /* we always specify '0' as BVCI in the templates below, as we override it with
1048 * 'p4' later anyway */
1049 pdu_rx := tr_BSSGP_PS_PAGING(0);
1050 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1051 if (ispresent(g_pars.p_tmsi)) {
1052 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1053 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1054 } else {
1055 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1056 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1057 }
1058 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1059 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1060 if (use_sig == false) {
1061 SGSN[sgsn_idx].send(pdu_tx);
1062 } else {
1063 SGSN_SIG[sgsn_idx].send(pdu_tx);
1064 }
1065 return pdu_rx;
1066}
1067
1068/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1069 * specified PCU index */
1070private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1071 boolean use_sig := false,integer pcu_idx := 0)
1072runs on BSSGP_ConnHdlr {
1073 var template (present) PDU_BSSGP exp_rx;
1074 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1075 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1076 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1077 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1078 timer T := 2.0;
1079 T.start;
1080 alt {
1081 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1082 setverdict(pass);
1083 repeat;
1084 }
1085 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1086 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1087 }
1088 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1089 setverdict(pass);
1090 repeat;
1091 }
1092 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1093 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1094 }
1095 [] any from PCU.receive(exp_rx) {
1096 setverdict(fail, "Paging received on unexpected BVC");
1097 }
1098 [] any from PCU_SIG.receive(exp_rx) {
1099 setverdict(fail, "Paging received on unexpected BVC");
1100 }
1101 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1102 setverdict(fail, "Different Paging than expected received PTP BVC");
1103 }
1104 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1105 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1106 }
1107 [] T.timeout;
1108 }
1109}
1110
Harald Welte7462a592020-11-23 22:07:07 +01001111/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1112private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1113 boolean use_sig := false)
1114runs on BSSGP_ConnHdlr {
1115 var template (present) PDU_BSSGP exp_rx;
1116 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1117 /* Expect paging to propagate to no BSS */
1118 timer T := 2.0;
1119 T.start;
1120 alt {
1121 [] any from PCU.receive(exp_rx) {
1122 setverdict(fail, "Paging received on unexpected BVC");
1123 }
1124 [] any from PCU_SIG.receive(exp_rx) {
1125 setverdict(fail, "Paging received on unexpected BVC");
1126 }
1127 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1128 setverdict(fail, "Different Paging received on PTP BVC");
1129 }
1130 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1131 setverdict(fail, "Different Paging received on SIGNALING BVC");
1132 }
1133 [] T.timeout {
1134 setverdict(pass);
1135 }
1136 }
1137}
1138
Harald Welte0e188242020-11-22 21:46:48 +01001139private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1140{
1141 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1142 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1143 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1144}
1145testcase TC_paging_ps_ptp_bss() runs on test_CT {
1146 var BSSGP_ConnHdlr vc_conn;
1147 f_init();
1148
1149 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1150 vc_conn.done;
1151
1152 f_cleanup();
1153}
1154
1155/* PS-PAGING on PTP-BVC for Location Area */
1156private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1157{
1158 var template (present) PDU_BSSGP exp_rx;
1159 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1160 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1161 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1162}
1163testcase TC_paging_ps_ptp_lac() runs on test_CT {
1164 var BSSGP_ConnHdlr vc_conn;
1165 f_init();
1166
1167 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1168 vc_conn.done;
1169
1170 f_cleanup();
1171}
1172
Harald Welte7462a592020-11-23 22:07:07 +01001173/* PS-PAGING on PTP-BVC for unknown Location Area */
1174private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1175{
1176 var GSM_Types.LocationAreaIdentification unknown_la := {
1177 mcc_mnc := '567F99'H,
1178 lac := 33333
1179 };
1180 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1181 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1182}
1183testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1184 var BSSGP_ConnHdlr vc_conn;
1185 f_init();
1186
1187 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1188 vc_conn.done;
1189
1190 f_cleanup();
1191}
1192
Harald Welte0e188242020-11-22 21:46:48 +01001193/* PS-PAGING on PTP-BVC for Routeing Area */
1194private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1195{
1196 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1197 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1198 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1199}
1200testcase TC_paging_ps_ptp_rac() runs on test_CT {
1201 var BSSGP_ConnHdlr vc_conn;
1202 f_init();
1203
1204 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1205 vc_conn.done;
1206
1207 f_cleanup();
1208}
1209
Harald Welte7462a592020-11-23 22:07:07 +01001210/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1211private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1212{
1213 var RoutingAreaIdentification unknown_ra := {
1214 lai := {
1215 mcc_mnc := '567F99'H,
1216 lac := 33333
1217 },
1218 rac := 254
1219 };
1220 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1221 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1222}
1223testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1224 var BSSGP_ConnHdlr vc_conn;
1225 f_init();
1226
1227 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1228 vc_conn.done;
1229
1230 f_cleanup();
1231}
1232
Harald Welte0e188242020-11-22 21:46:48 +01001233/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1234private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1235{
1236 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1237 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1238}
1239testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1240 var BSSGP_ConnHdlr vc_conn;
1241 f_init();
1242
1243 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1244 vc_conn.done;
1245
1246 f_cleanup();
1247}
1248
Harald Welte7462a592020-11-23 22:07:07 +01001249/* PS-PAGING on PTP-BVC for unknown BVCI */
1250private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1251{
1252 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1253 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1254}
1255testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1256 var BSSGP_ConnHdlr vc_conn;
1257 f_init();
1258
1259 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1260 vc_conn.done;
1261
1262 f_cleanup();
1263}
1264
Harald Welte0e188242020-11-22 21:46:48 +01001265/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1266private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1267runs on BSSGP_ConnHdlr {
1268[] PCU_SIG[pcu_idx].receive(exp_rx) {
1269 if (ro_integer_contains(roi, pcu_idx)) {
1270 setverdict(fail, "Received multiple paging on same SIG BVC");
1271 }
1272 roi := roi & { pcu_idx };
1273 repeat;
1274 }
1275[] PCU[pcu_idx].receive(exp_rx) {
1276 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1277 }
1278[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1279 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1280 }
1281[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1282 setverdict(fail, "Different Paging than expected received PTP BVC");
1283 }
1284}
1285
1286type record of default ro_default;
1287
1288/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1289private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1290 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1291{
1292 var template (present) PDU_BSSGP exp_rx;
1293 exp_rx := f_send_paging_ps(p4, 0, true);
1294
1295 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1296 var ro_default defaults := {};
1297 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1298 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1299 defaults := defaults & { d };
1300 }
1301 f_sleep(2.0);
1302 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1303 deactivate(defaults[i]);
1304 }
1305 log("Paging received on PCU ", g_roi);
1306
1307 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1308 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1309 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1310 if (exp_on_i and not rx_on_i) {
1311 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1312 }
1313 if (not exp_on_i and rx_on_i) {
1314 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1315 }
1316 }
1317 setverdict(pass);
1318}
1319
1320/* PS-PAGING on SIG-BVC for BSS Area */
1321private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1322{
1323 /* we expect the paging to arrive on all three NSE */
1324 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1325}
1326testcase TC_paging_ps_sig_bss() runs on test_CT {
1327 var BSSGP_ConnHdlr vc_conn;
1328 f_init();
1329
1330 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1331 vc_conn.done;
1332
1333 f_cleanup();
1334}
1335
1336/* PS-PAGING on SIG-BVC for Location Area */
1337private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1338{
1339 /* Both PCU index 0 and 1 have a BVC within the LAC */
1340 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1341}
1342testcase TC_paging_ps_sig_lac() runs on test_CT {
1343 var BSSGP_ConnHdlr vc_conn;
1344 f_init();
1345
1346 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1347 vc_conn.done;
1348
1349 f_cleanup();
1350}
1351
Harald Welte7462a592020-11-23 22:07:07 +01001352/* PS-PAGING on SIG-BVC for unknown Location Area */
1353private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1354{
1355 var GSM_Types.LocationAreaIdentification unknown_la := {
1356 mcc_mnc := '567F99'H,
1357 lac := 33333
1358 };
1359 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1360}
1361testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1362 var BSSGP_ConnHdlr vc_conn;
1363 f_init();
1364
1365 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1366 vc_conn.done;
1367
1368 f_cleanup();
1369}
1370
Harald Welte0e188242020-11-22 21:46:48 +01001371/* PS-PAGING on SIG-BVC for Routeing Area */
1372private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1373{
1374 /* Only PCU index 0 has a matching BVC within the LAC */
1375 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1376}
1377testcase TC_paging_ps_sig_rac() runs on test_CT {
1378 var BSSGP_ConnHdlr vc_conn;
1379 f_init();
1380
1381 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1382 vc_conn.done;
1383
1384 f_cleanup();
1385}
1386
Harald Welte7462a592020-11-23 22:07:07 +01001387/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1388private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1389{
1390 var RoutingAreaIdentification unknown_ra := {
1391 lai := {
1392 mcc_mnc := '567F99'H,
1393 lac := 33333
1394 },
1395 rac := 254
1396 };
1397 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1398}
1399testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1400 var BSSGP_ConnHdlr vc_conn;
1401 f_init();
1402
1403 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1404 vc_conn.done;
1405
1406 f_cleanup();
1407}
1408
Harald Welte0e188242020-11-22 21:46:48 +01001409/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1410private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1411{
1412 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1413}
1414testcase TC_paging_ps_sig_bvci() runs on test_CT {
1415 var BSSGP_ConnHdlr vc_conn;
1416 f_init();
1417
1418 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1419 vc_conn.done;
1420
1421 f_cleanup();
1422}
1423
Harald Welte7462a592020-11-23 22:07:07 +01001424/* PS-PAGING on SIG-BVC for unknown BVCI */
1425private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1426{
1427 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1428}
1429testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1430 var BSSGP_ConnHdlr vc_conn;
1431 f_init();
1432
1433 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1434 vc_conn.done;
1435
1436 f_cleanup();
1437}
1438
1439
Harald Welte0e188242020-11-22 21:46:48 +01001440
1441/***********************************************************************
1442 * PAGING CS procedure
1443 ***********************************************************************/
1444
1445private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1446 boolean use_sig := false)
1447runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1448 var template (value) PDU_BSSGP pdu_tx;
1449 var template (present) PDU_BSSGP pdu_rx;
1450 /* we always specify '0' as BVCI in the templates below, as we override it with
1451 * 'p4' later anyway */
1452 pdu_rx := tr_BSSGP_CS_PAGING(0);
1453 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1454 if (ispresent(g_pars.p_tmsi)) {
1455 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1456 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1457 } else {
1458 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1459 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1460 }
1461 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1462 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1463 if (use_sig == false) {
1464 SGSN[sgsn_idx].send(pdu_tx);
1465 } else {
1466 SGSN_SIG[sgsn_idx].send(pdu_tx);
1467 }
1468 return pdu_rx;
1469}
1470
1471/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1472 * specified PCU index */
1473private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1474 boolean use_sig := false,integer pcu_idx := 0)
1475runs on BSSGP_ConnHdlr {
1476 var template (present) PDU_BSSGP exp_rx;
1477 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1478 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1479 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1480 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1481 timer T := 2.0;
1482 T.start;
1483 alt {
1484 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1485 setverdict(pass);
1486 repeat;
1487 }
1488 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1489 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1490 }
1491 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1492 setverdict(pass);
1493 repeat;
1494 }
1495 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1496 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1497 }
1498 [] any from PCU.receive(exp_rx) {
1499 setverdict(fail, "Paging received on unexpected BVC");
1500 }
1501 [] any from PCU_SIG.receive(exp_rx) {
1502 setverdict(fail, "Paging received on unexpected BVC");
1503 }
1504 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1505 setverdict(fail, "Different Paging than expected received PTP BVC");
1506 }
1507 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1508 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1509 }
1510 [] T.timeout;
1511 }
1512}
1513
Harald Welte7462a592020-11-23 22:07:07 +01001514/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1515private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1516 boolean use_sig := false)
1517runs on BSSGP_ConnHdlr {
1518 var template (present) PDU_BSSGP exp_rx;
1519 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1520 /* Expect paging to propagate to no BSS */
1521 timer T := 2.0;
1522 T.start;
1523 alt {
1524 [] any from PCU.receive(exp_rx) {
1525 setverdict(fail, "Paging received on unexpected BVC");
1526 }
1527 [] any from PCU_SIG.receive(exp_rx) {
1528 setverdict(fail, "Paging received on unexpected BVC");
1529 }
1530 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1531 setverdict(fail, "Different Paging received on PTP BVC");
1532 }
1533 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1534 setverdict(fail, "Different Paging received on SIGNALING BVC");
1535 }
1536 [] T.timeout {
1537 setverdict(pass);
1538 }
1539 }
1540}
1541
Harald Welte0e188242020-11-22 21:46:48 +01001542private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1543{
1544 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1545 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1546 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1547}
1548testcase TC_paging_cs_ptp_bss() runs on test_CT {
1549 var BSSGP_ConnHdlr vc_conn;
1550 f_init();
1551
1552 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1553 vc_conn.done;
1554
1555 f_cleanup();
1556}
1557
1558/* CS-PAGING on PTP-BVC for Location Area */
1559private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1560{
1561 var template (present) PDU_BSSGP exp_rx;
1562 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1563 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1564 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1565}
1566testcase TC_paging_cs_ptp_lac() runs on test_CT {
1567 var BSSGP_ConnHdlr vc_conn;
1568 f_init();
1569
1570 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1571 vc_conn.done;
1572
1573 f_cleanup();
1574}
1575
Harald Welte7462a592020-11-23 22:07:07 +01001576/* CS-PAGING on PTP-BVC for unknown Location Area */
1577private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1578{
1579 var GSM_Types.LocationAreaIdentification unknown_la := {
1580 mcc_mnc := '567F99'H,
1581 lac := 33333
1582 };
1583 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1584 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1585}
1586testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1587 var BSSGP_ConnHdlr vc_conn;
1588 f_init();
1589
1590 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1591 vc_conn.done;
1592
1593 f_cleanup();
1594}
1595
Harald Welte0e188242020-11-22 21:46:48 +01001596/* CS-PAGING on PTP-BVC for Routeing Area */
1597private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1598{
1599 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1600 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1601 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1602}
1603testcase TC_paging_cs_ptp_rac() runs on test_CT {
1604 var BSSGP_ConnHdlr vc_conn;
1605 f_init();
1606
1607 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1608 vc_conn.done;
1609
1610 f_cleanup();
1611}
1612
Harald Welte7462a592020-11-23 22:07:07 +01001613/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1614private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1615{
1616 var RoutingAreaIdentification unknown_ra := {
1617 lai := {
1618 mcc_mnc := '567F99'H,
1619 lac := 33333
1620 },
1621 rac := 254
1622 };
1623 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1624 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1625}
1626testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1627 var BSSGP_ConnHdlr vc_conn;
1628 f_init();
1629
1630 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1631 vc_conn.done;
1632
1633 f_cleanup();
1634}
1635
Harald Welte0e188242020-11-22 21:46:48 +01001636/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1637private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1638{
1639 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1640 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1641}
1642testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1643 var BSSGP_ConnHdlr vc_conn;
1644 f_init();
1645
1646 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1647 vc_conn.done;
1648
1649 f_cleanup();
1650}
1651
Harald Welte7462a592020-11-23 22:07:07 +01001652/* CS-PAGING on PTP-BVC for unknown BVCI */
1653private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1654{
1655 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1656 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1657}
1658testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1659 var BSSGP_ConnHdlr vc_conn;
1660 f_init();
1661
1662 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1663 vc_conn.done;
1664
1665 f_cleanup();
1666}
1667
Harald Welte0e188242020-11-22 21:46:48 +01001668/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1669private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1670 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1671{
1672 var template (present) PDU_BSSGP exp_rx;
1673 exp_rx := f_send_paging_cs(p4, 0, true);
1674
1675 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1676 var ro_default defaults := {};
1677 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1678 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1679 defaults := defaults & { d };
1680 }
1681 f_sleep(2.0);
1682 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1683 deactivate(defaults[i]);
1684 }
1685 log("Paging received on PCU ", g_roi);
1686
1687 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1688 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1689 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1690 if (exp_on_i and not rx_on_i) {
1691 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1692 }
1693 if (not exp_on_i and rx_on_i) {
1694 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1695 }
1696 }
1697 setverdict(pass);
1698}
1699
1700/* CS-PAGING on SIG-BVC for BSS Area */
1701private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1702{
1703 /* we expect the paging to arrive on all three NSE */
1704 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1705}
1706testcase TC_paging_cs_sig_bss() runs on test_CT {
1707 var BSSGP_ConnHdlr vc_conn;
1708 f_init();
1709
1710 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1711 vc_conn.done;
1712
1713 f_cleanup();
1714}
1715
1716/* CS-PAGING on SIG-BVC for Location Area */
1717private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1718{
1719 /* Both PCU index 0 and 1 have a BVC within the LAC */
1720 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1721}
1722testcase TC_paging_cs_sig_lac() runs on test_CT {
1723 var BSSGP_ConnHdlr vc_conn;
1724 f_init();
1725
1726 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1727 vc_conn.done;
1728
1729 f_cleanup();
1730}
1731
Harald Welte7462a592020-11-23 22:07:07 +01001732/* CS-PAGING on SIG-BVC for unknown Location Area */
1733private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1734{
1735 var GSM_Types.LocationAreaIdentification unknown_la := {
1736 mcc_mnc := '567F99'H,
1737 lac := 33333
1738 };
1739 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1740}
1741testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1742 var BSSGP_ConnHdlr vc_conn;
1743 f_init();
1744
1745 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1746 vc_conn.done;
1747
1748 f_cleanup();
1749}
1750
Harald Welte0e188242020-11-22 21:46:48 +01001751/* CS-PAGING on SIG-BVC for Routeing Area */
1752private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1753{
1754 /* Only PCU index 0 has a matching BVC within the LAC */
1755 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1756}
1757testcase TC_paging_cs_sig_rac() runs on test_CT {
1758 var BSSGP_ConnHdlr vc_conn;
1759 f_init();
1760
1761 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1762 vc_conn.done;
1763
1764 f_cleanup();
1765}
1766
Harald Welte7462a592020-11-23 22:07:07 +01001767/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1768private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1769{
1770 var RoutingAreaIdentification unknown_ra := {
1771 lai := {
1772 mcc_mnc := '567F99'H,
1773 lac := 33333
1774 },
1775 rac := 254
1776 };
1777 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1778}
1779testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1780 var BSSGP_ConnHdlr vc_conn;
1781 f_init();
1782
1783 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1784 vc_conn.done;
1785
1786 f_cleanup();
1787}
1788
Harald Welte0e188242020-11-22 21:46:48 +01001789/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1790private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1791{
1792 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1793}
1794testcase TC_paging_cs_sig_bvci() runs on test_CT {
1795 var BSSGP_ConnHdlr vc_conn;
1796 f_init();
1797
1798 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1799 vc_conn.done;
1800
1801 f_cleanup();
1802}
1803
Harald Welte7462a592020-11-23 22:07:07 +01001804/* CS-PAGING on SIG-BVC for unknown BVCI */
1805private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1806{
1807 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1808}
1809testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1810 var BSSGP_ConnHdlr vc_conn;
1811 f_init();
1812
1813 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1814 vc_conn.done;
1815
1816 f_cleanup();
1817}
1818
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001819private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1820 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1821 var integer i;
1822 for (i := 0; i < 10; i := i+1) {
1823 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1824 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1825 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1826
1827 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1828
1829 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1830 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1831 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1832
1833 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1834 }
1835 setverdict(pass);
1836}
1837testcase TC_flush_ll() runs on test_CT
1838{
1839 var BSSGP_ConnHdlr vc_conn;
1840 f_init();
1841
1842 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1843 vc_conn.done;
1844 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1845
1846 f_cleanup();
1847}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001848
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001849private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1850runs on GlobalTest_CT {
1851[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1852 if (ro_integer_contains(roi, pcu_idx)) {
1853 setverdict(fail, "Received multiple on same SIG BVC");
1854 }
1855 roi := roi & { pcu_idx };
1856 repeat;
1857 }
1858}
1859/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1860testcase TC_trace() runs on GlobalTest_CT
1861{
1862 var BSSGP_ConnHdlr vc_conn;
1863 f_init();
1864 f_global_init();
1865
1866 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1867 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1868
1869 var ro_default defaults := {};
1870 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1871 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1872 }
1873 G_SGSN[0].send(pdu_tx);
1874 f_sleep(2.0);
1875 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1876 deactivate(defaults[i]);
1877 }
1878
1879 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1880 if (not ro_integer_contains(g_roi, i)) {
1881 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
1882 }
1883 }
1884 setverdict(pass);
1885
1886 f_cleanup();
1887}
1888
Harald Weltec0351d12020-11-27 22:49:02 +01001889private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
1890 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1891
1892 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
1893 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1894 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
1895
1896 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1897
1898 setverdict(pass);
1899}
1900/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
1901testcase TC_llc_discarded() runs on test_CT
1902{
1903 var BSSGP_ConnHdlr vc_conn;
1904 f_init();
1905
1906 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
1907 vc_conn.done;
1908 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1909
1910 f_cleanup();
1911}
1912
Harald Weltef20af412020-11-28 16:11:11 +01001913/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
1914testcase TC_overload() runs on GlobalTest_CT
1915{
1916 f_init();
1917 f_global_init();
1918
1919 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
1920 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
1921
1922 var ro_default defaults := {};
1923 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1924 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1925 }
1926 G_SGSN[0].send(pdu_tx);
1927 f_sleep(2.0);
1928 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1929 deactivate(defaults[i]);
1930 }
1931
1932 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1933 if (not ro_integer_contains(g_roi, i)) {
1934 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
1935 }
1936 }
1937 setverdict(pass);
1938
1939 f_cleanup();
1940}
1941
Harald Welte239aa502020-11-24 23:14:20 +01001942private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1943{
1944 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1945 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1946 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1947
1948 SGSN_MGMT.clear;
1949 PCU_MGMT.clear;
1950
1951 /* block the PTP BVC from the PCU side */
1952 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
1953 /* expect state on both PCU and SGSN side to change */
1954 interleave {
1955 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
1956 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
1957 }
1958 setverdict(pass);
1959}
1960testcase TC_bvc_block_ptp() runs on test_CT
1961{
1962 f_init();
1963 f_sleep(1.0);
1964 f_block_ptp_bvc_from_pcu(0, 0);
1965 f_cleanup();
1966}
1967
1968private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1969{
1970 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1971 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1972 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1973
1974 SGSN_MGMT.clear;
1975 PCU_MGMT.clear;
1976
1977 /* block the PTP BVC from the PCU side */
1978 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
1979 /* expect state on both PCU and SGSN side to change */
1980 interleave {
1981 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
1982 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
1983 }
1984 setverdict(pass);
1985}
1986testcase TC_bvc_unblock_ptp() runs on test_CT
1987{
1988 f_init();
1989 f_sleep(1.0);
1990 f_block_ptp_bvc_from_pcu(0, 0);
1991 f_sleep(1.0);
1992 f_unblock_ptp_bvc_from_pcu(0, 0);
1993 f_cleanup();
1994}
1995
Harald Welte60a8ec72020-11-25 17:12:53 +01001996private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
1997[] pt.receive(BssgpStatusIndication:?) { repeat; }
1998}
1999private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2000 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2001 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2002 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2003 }
2004 }
2005 return null;
2006}
2007private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2008{
2009 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2010 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2011 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2012 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2013 var default d;
2014
2015 SGSN_MGMT.clear;
2016 PCU_MGMT.clear;
2017
2018 /* block the PTP BVC from the PCU side */
2019 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2020 /* expect state on both PCU and SGSN side to change */
2021 d := activate(as_ignore_status(SGSN_MGMT));
2022 interleave {
2023 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2024 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2025 }
2026 deactivate(d);
2027 setverdict(pass);
2028}
2029/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2030testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2031{
2032 f_init();
2033 f_sleep(3.0);
2034 f_reset_ptp_bvc_from_pcu(0, 0);
2035 f_cleanup();
2036}
2037
Harald Welte16786e92020-11-27 19:11:56 +01002038private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2039runs on test_CT {
2040 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2041 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2042 roi := roi & { bvci };
2043 }
2044}
2045/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2046testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2047
2048 f_init();
2049 f_sleep(3.0);
2050
2051 /* Start BVC-RESET procedure for BVCI=0 */
2052 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2053
2054 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2055 var ro_default defaults := {};
2056 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2057 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2058 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2059 defaults := defaults & { d };
2060 }
2061
2062 timer T := 3.0;
2063 T.start;
2064 alt {
2065 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2066 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2067 }
2068 [] T.timeout;
2069 }
2070
2071 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2072 deactivate(defaults[i]);
2073 }
2074
2075 /* check if BVC-block was received on all expected BVC */
2076 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2077 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2078 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2079 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2080 }
2081 }
2082
2083 /* check if BVC-block was not received on any unexpected BVC is not required as
2084 * such a message would basically run into 'no matching clause' */
2085
2086 f_cleanup();
2087}
2088
Harald Welte60a8ec72020-11-25 17:12:53 +01002089private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2090{
2091 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2092 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2093 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2094 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2095 var default d;
2096
2097 SGSN_MGMT.clear;
2098 PCU_MGMT.clear;
2099
2100 /* block the PTP BVC from the PCU side */
2101 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2102 /* expect state on both PCU and SGSN side to change */
2103 d := activate(as_ignore_status(PCU_MGMT));
2104 interleave {
2105 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2106 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2107 }
2108 deactivate(d);
2109 setverdict(pass);
2110}
2111/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2112testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2113{
2114 f_init();
2115 f_sleep(3.0);
2116 f_reset_ptp_bvc_from_sgsn(0, 0);
2117 f_cleanup();
2118}
2119
Harald Welte16786e92020-11-27 19:11:56 +01002120private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2121runs on test_CT {
2122 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2123 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2124 roi := roi & { nsei };
2125 }
2126}
2127/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2128testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2129
2130 f_init();
2131 f_sleep(3.0);
2132
2133 /* Start BVC-RESET procedure for BVCI=0 */
2134 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2135
2136 /* Activate altsteps: One for each PCU NSE */
2137 var ro_default defaults := {};
2138 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2139 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2140 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2141 defaults := defaults & { d };
2142 }
2143
2144 f_sleep(3.0);
2145
2146 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2147 deactivate(defaults[i]);
2148 }
2149
2150 /* check if BVC-block was received on all expected BVC */
2151 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2152 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2153 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2154 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2155 }
2156 }
2157
2158 /* check if BVC-block was not received on any unexpected BVC is not required as
2159 * such a message would basically run into 'no matching clause' */
2160
2161 f_cleanup();
2162}
2163
Daniel Willmann423d8f42020-09-08 18:58:22 +02002164control {
2165 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002166 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002167 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002168 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002169 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002170 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002171 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002172 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002173 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002174 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002175 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002176 execute( TC_bvc_block_ptp() );
2177 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002178 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002179 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002180 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002181 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef8ef0282020-11-18 12:16:59 +01002182 if (false) {
2183 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2184 execute( TC_load_sharing_dl() );
2185 }
Harald Welte0e188242020-11-22 21:46:48 +01002186
2187 /* PAGING-PS over PTP BVC */
2188 execute( TC_paging_ps_ptp_bss() );
2189 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002190 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002191 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002192 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002193 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002194 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002195
2196 /* PAGING-PS over SIG BVC */
2197 execute( TC_paging_ps_sig_bss() );
2198 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002199 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002200 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002201 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002202 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002203 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002204
2205 /* PAGING-CS over PTP BVC */
2206 execute( TC_paging_cs_ptp_bss() );
2207 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002208 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002209 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002210 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002211 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002212 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002213
2214 /* PAGING-CS over SIG BVC */
2215 execute( TC_paging_cs_sig_bss() );
2216 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002217 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002218 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002219 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002220 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002221 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002222
2223
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002224 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002225}
2226
2227
2228}