blob: 5bb77d325c8e0b82d4960483d804b38350eb16eb [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 Welte951e6a92020-12-02 19:08:45 +0100378 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
Harald Welteb419d0e2020-11-16 16:45:05 +0100379 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100380 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100381
382 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100383 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100384 T.start;
385 alt {
386 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
387 bvci_unblocked := bvci_unblocked & { bsi.bvci };
388 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
389 repeat;
390 }
391 }
392 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
393 repeat;
394 }
Harald Welte3c905152020-11-26 20:56:09 +0100395 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
396 repeat;
397 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100398 [] SGSN_MGMT.receive {
399 setverdict(fail, "Received unexpected message on SGSN_MGMT");
400 mtc.stop;
401 }
402
403 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
404 repeat;
405 }
406 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
407 repeat;
408 }
409 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
410 repeat;
411 }
412 [] PCU_MGMT.receive {
413 setverdict(fail, "Received unexpected message on PCU_MGMT");
414 mtc.stop;
415 }
416
417 [] T.timeout {
418 setverdict(fail, "Timeout waiting for unblock of all BVCs");
419 mtc.stop;
420 }
421 }
422
423 /* iterate over list and check all BVCI */
424 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
425 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
426 if (not ro_integer_contains(bvci_unblocked, bvci)) {
427 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
428 mtc.stop;
429 }
430 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200431}
432
433function f_cleanup() runs on test_CT {
434 self.stop;
435}
436
437type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
438
439/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100440function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200441 float t_guard := 30.0)
442runs on test_CT return BSSGP_ConnHdlr {
443 var BSSGP_ConnHdlr vc_conn;
444
445 var BSSGP_ConnHdlrPars pars := {
446 imei := f_gen_imei(imsi_suffix),
447 imsi := f_gen_imsi(imsi_suffix),
448 msisdn := f_gen_msisdn(imsi_suffix),
449 p_tmsi := omit,
450 p_tmsi_sig := omit,
451 tlli := f_gprs_tlli_random(),
452 tlli_old := omit,
453 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100454 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100455 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200456 t_guard := t_guard
457 };
458
459 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200460
461 vc_conn.start(f_handler_init(fn, id, pars));
462 return vc_conn;
463}
464
Harald Welte3dd21b32020-11-17 19:21:00 +0100465/* 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 +0100466private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
467runs on BSSGP_ConnHdlr {
468 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100469 if (PCU[port_idx].checkstate("Connected")) {
470 /* unregister + disconnect from old BVC */
471 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
472 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
473 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
474 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
475 }
476 /* connect to new BVC and register us */
477 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
478 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
479 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
480 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
481 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100482 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100483}
484
485/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
486private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
487 if (SGSN[port_idx].checkstate("Connected")) {
488 /* unregister + disconnect from old BVC */
489 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
490 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
491 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
492 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
493 }
494 /* connect to new BVC and register us */
495 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
496 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
497 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
498 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
499 sgsn_ct[port_idx] := bvc_ct;
500}
501
Daniel Willmann423d8f42020-09-08 18:58:22 +0200502private altstep as_Tguard() runs on BSSGP_ConnHdlr {
503 [] g_Tguard.timeout {
504 setverdict(fail, "Tguard timeout");
505 mtc.stop;
506 }
507}
508
509/* first function called in every ConnHdlr */
510private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
511runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100512 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200513 /* do some common stuff like setting up g_pars */
514 g_pars := pars;
515
516 llc := f_llc_create(false);
517
Harald Welte3dd21b32020-11-17 19:21:00 +0100518 /* default connections on PCU side: First BVC of each NSE/PCU */
519 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100520 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100521 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100522
523 /* default connections on SGSN side: First BVC of each NSE/SGSN */
524 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
525 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100526 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200527
528 g_Tguard.start(pars.t_guard);
529 activate(as_Tguard());
530
531 /* call the user-supplied test case function */
532 fn.apply(id);
533}
534
Harald Welte1e834f32020-11-15 20:02:59 +0100535private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
536runs on BSSGP_ConnHdlr {
537 PT.call(BSSGP_register_client:{imsi, tlli}) {
538 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
539 }
540}
541
542private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
543runs on BSSGP_ConnHdlr {
544 PT.call(BSSGP_unregister_client:{imsi}) {
545 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
546 }
547}
548
Harald Welte22ef5d92020-11-16 13:35:14 +0100549/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
550friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100551 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100552 var PDU_BSSGP rx;
553 timer T := 1.0;
554
Daniel Willmann4798fd72020-11-24 16:23:29 +0100555 if (use_sig) {
556 PCU_SIG[pcu_idx].send(tx);
557 } else {
558 PCU[pcu_idx].send(tx);
559 }
560
Harald Welte22ef5d92020-11-16 13:35:14 +0100561 T.start;
562 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100563 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
564 setverdict(pass);
565 }
566 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100567 setverdict(pass);
568 }
569 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
570 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
571 mtc.stop;
572 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100573 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
574 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
575 mtc.stop;
576 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100577 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100578 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100579 mtc.stop;
580 }
581 }
582}
583
584/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
585friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100586 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100587 var PDU_BSSGP rx;
588 timer T := 1.0;
589
Daniel Willmann4798fd72020-11-24 16:23:29 +0100590 if (use_sig) {
591 SGSN_SIG[sgsn_idx].send(tx);
592 } else {
593 SGSN[sgsn_idx].send(tx);
594 }
595
Harald Welte22ef5d92020-11-16 13:35:14 +0100596 T.start;
597 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100598 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
599 setverdict(pass);
600 }
601 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100602 setverdict(pass);
603 }
604 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
605 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
606 mtc.stop;
607 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100608 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
609 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
610 mtc.stop;
611 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100612 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100613 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100614 mtc.stop;
615 }
616 }
617}
Harald Welte1e834f32020-11-15 20:02:59 +0100618
Harald Welte3807ed12020-11-24 19:05:22 +0100619/***********************************************************************
620 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
621 ***********************************************************************/
622
623type component GlobalTest_CT extends test_CT {
624 port BSSGP_PT G_PCU[NUM_PCU];
625 port BSSGP_PT G_SGSN[NUM_SGSN];
626};
627
628private function f_global_init() runs on GlobalTest_CT {
629 var integer i;
630 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
631 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
632 }
633 for (i := 0; i < lengthof(g_pcu); i := i+1) {
634 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
635 }
636}
637
638/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
639friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
640 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
641 var PDU_BSSGP rx;
642 timer T := 1.0;
643
644 G_PCU[pcu_idx].send(tx);
645 T.start;
646 alt {
647 [] G_SGSN[sgsn_idx].receive(exp_rx) {
648 setverdict(pass);
649 }
650 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
651 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
652 mtc.stop;
653 }
654 [] T.timeout {
655 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
656 mtc.stop;
657 }
658 }
659}
660
661/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
662friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
663 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
664 var PDU_BSSGP rx;
665 timer T := 1.0;
666
667 G_SGSN[sgsn_idx].send(tx);
668 T.start;
669 alt {
670 [] G_PCU[pcu_idx].receive(exp_rx) {
671 setverdict(pass);
672 }
673 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
674 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
675 mtc.stop;
676 }
677 [] T.timeout {
678 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
679 mtc.stop;
680 }
681 }
682}
683
684
Daniel Willmann423d8f42020-09-08 18:58:22 +0200685/* TODO:
686 * Detach without Attach
687 * SM procedures without attach / RAU
688 * ATTACH / RAU
689 ** with / without authentication
690 ** with / without P-TMSI allocation
691 * re-transmissions of LLC frames
692 * PDP Context activation
693 ** with different GGSN config in SGSN VTY
694 ** with different PDP context type (v4/v6/v46)
695 ** timeout from GGSN
696 ** multiple / secondary PDP context
697 */
698
699private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
700 f_sleep(5.0);
701 setverdict(pass);
702}
703
704testcase TC_BVC_bringup() runs on test_CT {
705 var BSSGP_ConnHdlr vc_conn;
706 f_init();
707
708 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
709 vc_conn.done;
710
711 f_cleanup();
712}
713
714friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100715 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200716 timer T := 5.0;
717 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100718 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200719 T.start;
720 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100721 [] 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 +0200722 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
723 }
Harald Welte16357a92020-11-17 18:20:00 +0100724 [] 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 +0200725 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
726 mtc.stop;
727 }
728 [] T.timeout {
729 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
730 mtc.stop;
731 }
732 }
733 return '00'O;
734}
735
736friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100737 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200738 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100739 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 +0200740 T.start;
741 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100742 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
743 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200744 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
745 mtc.stop;
746 }
747 [] T.timeout {
748 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
749 mtc.stop;
750 }
751 }
752}
753
754
Harald Welte92686012020-11-15 21:45:49 +0100755/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
756private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100757 var integer ran_idx := 0;
758 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100759 var integer i;
760
Harald Welte0d5fceb2020-11-29 16:04:07 +0100761 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100762 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100763 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 +0100764 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100765 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 +0100766
Harald Welte0d5fceb2020-11-29 16:04:07 +0100767 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100768 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100769 }
770 setverdict(pass);
771}
772
773testcase TC_ul_unitdata() runs on test_CT
774{
775 var BSSGP_ConnHdlr vc_conn;
776 f_init();
777
778 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
779 vc_conn.done;
780 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
781
782 f_cleanup();
783}
784
Harald Welte78d8db92020-11-15 23:27:27 +0100785/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
786private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
787 var integer i;
788
Harald Welte0d5fceb2020-11-29 16:04:07 +0100789 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100790 var octetstring payload := f_rnd_octstring(i);
791 var template (value) PDU_BSSGP pdu_tx :=
792 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
793 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
794 var template (present) PDU_BSSGP pdu_rx :=
795 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
796
Harald Welte0d5fceb2020-11-29 16:04:07 +0100797 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100798 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100799 }
800 setverdict(pass);
801}
802
803testcase TC_dl_unitdata() runs on test_CT
804{
805 var BSSGP_ConnHdlr vc_conn;
806 f_init();
807
808 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
809 vc_conn.done;
810 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
811
812 f_cleanup();
813}
Harald Welte92686012020-11-15 21:45:49 +0100814
Harald Welte6dc2ac42020-11-16 09:16:17 +0100815private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
816 var integer i;
817
818 for (i := 0; i < 10; i := i+1) {
819 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
820 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
821 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
822
Harald Welte22ef5d92020-11-16 13:35:14 +0100823 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100824 }
825 setverdict(pass);
826}
827testcase TC_ra_capability() runs on test_CT
828{
829 var BSSGP_ConnHdlr vc_conn;
830 f_init();
831
832 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
833 vc_conn.done;
834 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
835
836 f_cleanup();
837}
838
Daniel Willmannace3ece2020-11-16 19:53:26 +0100839private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
840 var integer i;
841 var OCT1 tag;
842 for (i := 0; i < 10; i := i+1) {
843 tag := int2oct(23 + i, 1);
844 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
845 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
846 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
847
848 f_pcu2sgsn(pdu_tx, pdu_rx);
849
850 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
851 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
852 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
853
854 f_sgsn2pcu(pdu_tx, pdu_rx);
855 }
856 setverdict(pass);
857}
858testcase TC_ra_capability_upd() runs on test_CT
859{
860 var BSSGP_ConnHdlr vc_conn;
861 f_init();
862
Daniel Willmann54833f22020-11-19 15:43:52 +0100863 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100864 vc_conn.done;
865 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
866
867 f_cleanup();
868}
869
Daniel Willmann165d6612020-11-19 14:27:29 +0100870private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
871 var integer i;
872 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
873 for (i := 0; i < 10; i := i+1) {
874 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
875 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
876 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
877
878 f_pcu2sgsn(pdu_tx, pdu_rx);
879 }
880 setverdict(pass);
881}
882testcase TC_radio_status() runs on test_CT
883{
884 var BSSGP_ConnHdlr vc_conn;
885 f_init();
886
Daniel Willmann54833f22020-11-19 15:43:52 +0100887 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100888 vc_conn.done;
889 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
890
891 f_cleanup();
892}
893
Harald Welte3807ed12020-11-24 19:05:22 +0100894private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100895 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100896
Daniel Willmannfa67f492020-11-19 15:48:05 +0100897 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100898 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100899 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100900 var OCT4 tlli := f_gprs_tlli_random();
901 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100902 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100903 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100904
Harald Welte3807ed12020-11-24 19:05:22 +0100905 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100906
Harald Welte3807ed12020-11-24 19:05:22 +0100907 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100908 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100909 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100910
Harald Welte3807ed12020-11-24 19:05:22 +0100911 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100912
913 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100914 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100915 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100916 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100917
Harald Welte3807ed12020-11-24 19:05:22 +0100918 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100919 }
920 setverdict(pass);
921}
Harald Welte3807ed12020-11-24 19:05:22 +0100922testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100923{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100924 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100925 f_global_init();
926 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +0100927 f_cleanup();
928}
Harald Welte6dc2ac42020-11-16 09:16:17 +0100929
Harald Welte3807ed12020-11-24 19:05:22 +0100930private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +0100931 var integer i;
932
933 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100934 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +0100935 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100936 var OCT4 tlli := f_gprs_tlli_random();
937 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100938 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100939 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100940
Harald Welte3807ed12020-11-24 19:05:22 +0100941 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100942
Harald Welte3807ed12020-11-24 19:05:22 +0100943 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100944 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100945 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100946
Harald Welte3807ed12020-11-24 19:05:22 +0100947 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100948
949 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100950 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100951 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100952 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100953
Harald Welte3807ed12020-11-24 19:05:22 +0100954 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100955 }
956 setverdict(pass);
957}
Harald Welte3807ed12020-11-24 19:05:22 +0100958testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +0100959{
Daniel Willmann087a33d2020-11-19 15:58:43 +0100960 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100961 f_global_init();
962 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +0100963 f_cleanup();
964}
965
Harald Weltef8ef0282020-11-18 12:16:59 +0100966/* test the load-sharing between multiple NS-VC on the BSS side */
967private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
968 var integer i;
969
970 for (i := 0; i < 10; i := i+1) {
971 var octetstring payload := f_rnd_octstring(i);
972 var template (value) PDU_BSSGP pdu_tx :=
973 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
974 SGSN[0].send(pdu_tx);
975 }
976 setverdict(pass);
977}
978testcase TC_load_sharing_dl() runs on test_CT_NS
979{
980 const integer num_ue := 10;
981 var BSSGP_ConnHdlr vc_conn[num_ue];
982 f_init();
983
984 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
985 * side so we get the raw NsUnitdataIndication and hence observe different
986 * NSVCI */
987 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
988 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
989
990 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
991 * of the NS-VC is ALIVE/UNBLOCKED */
992 f_sleep(3.0);
993
994 /* start parallel components generating DL-UNITDATA from the SGSN side */
995 for (var integer i:= 0; i < num_ue; i := i+1) {
996 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
997 }
998
999 /* now start counting all the messages that were queued before */
1000 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1001 var ro_integer rx_count := { 0, 0, 0, 0 };
1002 timer T := 2.0;
1003 T.start;
1004 alt {
1005 [] as_NsUdiCount(0, rx_count);
1006 [] as_NsUdiCount(1, rx_count);
1007 [] as_NsUdiCount(2, rx_count);
1008 [] as_NsUdiCount(3, rx_count);
1009 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1010 [] NS.receive(NsStatusIndication:?) { repeat; }
1011 [] NS.receive {
1012 setverdict(fail, "Rx unexpected NS");
1013 mtc.stop;
1014 }
1015 [] T.timeout {
1016 }
1017 }
1018 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1019 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1020 if (rx_count[i] == 0) {
1021 setverdict(fail, "Data not shared over all NSVC");
1022 }
1023 }
1024 setverdict(pass);
1025}
1026private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1027 var NsUnitdataIndication udi;
1028 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1029 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1030 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1031 repeat;
1032 }
1033}
1034type component test_CT_NS extends test_CT {
1035 port NS_PT NS;
1036};
1037
1038
Harald Welte0e188242020-11-22 21:46:48 +01001039/***********************************************************************
1040 * PAGING PS procedure
1041 ***********************************************************************/
1042
1043private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1044 boolean use_sig := false)
1045runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1046 var template (value) PDU_BSSGP pdu_tx;
1047 var template (present) PDU_BSSGP pdu_rx;
1048 /* we always specify '0' as BVCI in the templates below, as we override it with
1049 * 'p4' later anyway */
1050 pdu_rx := tr_BSSGP_PS_PAGING(0);
1051 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1052 if (ispresent(g_pars.p_tmsi)) {
1053 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1054 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1055 } else {
1056 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1057 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1058 }
1059 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1060 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1061 if (use_sig == false) {
1062 SGSN[sgsn_idx].send(pdu_tx);
1063 } else {
1064 SGSN_SIG[sgsn_idx].send(pdu_tx);
1065 }
1066 return pdu_rx;
1067}
1068
1069/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1070 * specified PCU index */
1071private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1072 boolean use_sig := false,integer pcu_idx := 0)
1073runs on BSSGP_ConnHdlr {
1074 var template (present) PDU_BSSGP exp_rx;
1075 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1076 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1077 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1078 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1079 timer T := 2.0;
1080 T.start;
1081 alt {
1082 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1083 setverdict(pass);
1084 repeat;
1085 }
1086 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1087 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1088 }
1089 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1090 setverdict(pass);
1091 repeat;
1092 }
1093 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1094 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1095 }
1096 [] any from PCU.receive(exp_rx) {
1097 setverdict(fail, "Paging received on unexpected BVC");
1098 }
1099 [] any from PCU_SIG.receive(exp_rx) {
1100 setverdict(fail, "Paging received on unexpected BVC");
1101 }
1102 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1103 setverdict(fail, "Different Paging than expected received PTP BVC");
1104 }
1105 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1106 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1107 }
1108 [] T.timeout;
1109 }
1110}
1111
Harald Welte7462a592020-11-23 22:07:07 +01001112/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1113private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1114 boolean use_sig := false)
1115runs on BSSGP_ConnHdlr {
1116 var template (present) PDU_BSSGP exp_rx;
1117 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1118 /* Expect paging to propagate to no BSS */
1119 timer T := 2.0;
1120 T.start;
1121 alt {
1122 [] any from PCU.receive(exp_rx) {
1123 setverdict(fail, "Paging received on unexpected BVC");
1124 }
1125 [] any from PCU_SIG.receive(exp_rx) {
1126 setverdict(fail, "Paging received on unexpected BVC");
1127 }
1128 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1129 setverdict(fail, "Different Paging received on PTP BVC");
1130 }
1131 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1132 setverdict(fail, "Different Paging received on SIGNALING BVC");
1133 }
1134 [] T.timeout {
1135 setverdict(pass);
1136 }
1137 }
1138}
1139
Harald Welte0e188242020-11-22 21:46:48 +01001140private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1141{
1142 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1143 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1144 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1145}
1146testcase TC_paging_ps_ptp_bss() runs on test_CT {
1147 var BSSGP_ConnHdlr vc_conn;
1148 f_init();
1149
1150 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1151 vc_conn.done;
1152
1153 f_cleanup();
1154}
1155
1156/* PS-PAGING on PTP-BVC for Location Area */
1157private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1158{
1159 var template (present) PDU_BSSGP exp_rx;
1160 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1161 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1162 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1163}
1164testcase TC_paging_ps_ptp_lac() runs on test_CT {
1165 var BSSGP_ConnHdlr vc_conn;
1166 f_init();
1167
1168 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1169 vc_conn.done;
1170
1171 f_cleanup();
1172}
1173
Harald Welte7462a592020-11-23 22:07:07 +01001174/* PS-PAGING on PTP-BVC for unknown Location Area */
1175private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1176{
1177 var GSM_Types.LocationAreaIdentification unknown_la := {
1178 mcc_mnc := '567F99'H,
1179 lac := 33333
1180 };
1181 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1182 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1183}
1184testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1185 var BSSGP_ConnHdlr vc_conn;
1186 f_init();
1187
1188 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1189 vc_conn.done;
1190
1191 f_cleanup();
1192}
1193
Harald Welte0e188242020-11-22 21:46:48 +01001194/* PS-PAGING on PTP-BVC for Routeing Area */
1195private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1196{
1197 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1198 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1199 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1200}
1201testcase TC_paging_ps_ptp_rac() runs on test_CT {
1202 var BSSGP_ConnHdlr vc_conn;
1203 f_init();
1204
1205 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1206 vc_conn.done;
1207
1208 f_cleanup();
1209}
1210
Harald Welte7462a592020-11-23 22:07:07 +01001211/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1212private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1213{
1214 var RoutingAreaIdentification unknown_ra := {
1215 lai := {
1216 mcc_mnc := '567F99'H,
1217 lac := 33333
1218 },
1219 rac := 254
1220 };
1221 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1222 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1223}
1224testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1225 var BSSGP_ConnHdlr vc_conn;
1226 f_init();
1227
1228 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1229 vc_conn.done;
1230
1231 f_cleanup();
1232}
1233
Harald Welte0e188242020-11-22 21:46:48 +01001234/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1235private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1236{
1237 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1238 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1239}
1240testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1241 var BSSGP_ConnHdlr vc_conn;
1242 f_init();
1243
1244 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1245 vc_conn.done;
1246
1247 f_cleanup();
1248}
1249
Harald Welte7462a592020-11-23 22:07:07 +01001250/* PS-PAGING on PTP-BVC for unknown BVCI */
1251private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1252{
1253 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1254 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1255}
1256testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1257 var BSSGP_ConnHdlr vc_conn;
1258 f_init();
1259
1260 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1261 vc_conn.done;
1262
1263 f_cleanup();
1264}
1265
Harald Welte0e188242020-11-22 21:46:48 +01001266/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1267private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1268runs on BSSGP_ConnHdlr {
1269[] PCU_SIG[pcu_idx].receive(exp_rx) {
1270 if (ro_integer_contains(roi, pcu_idx)) {
1271 setverdict(fail, "Received multiple paging on same SIG BVC");
1272 }
1273 roi := roi & { pcu_idx };
1274 repeat;
1275 }
1276[] PCU[pcu_idx].receive(exp_rx) {
1277 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1278 }
1279[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1280 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1281 }
1282[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1283 setverdict(fail, "Different Paging than expected received PTP BVC");
1284 }
1285}
1286
1287type record of default ro_default;
1288
1289/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1290private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1291 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1292{
1293 var template (present) PDU_BSSGP exp_rx;
1294 exp_rx := f_send_paging_ps(p4, 0, true);
1295
1296 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1297 var ro_default defaults := {};
1298 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1299 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1300 defaults := defaults & { d };
1301 }
1302 f_sleep(2.0);
1303 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1304 deactivate(defaults[i]);
1305 }
1306 log("Paging received on PCU ", g_roi);
1307
1308 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1309 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1310 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1311 if (exp_on_i and not rx_on_i) {
1312 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1313 }
1314 if (not exp_on_i and rx_on_i) {
1315 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1316 }
1317 }
1318 setverdict(pass);
1319}
1320
1321/* PS-PAGING on SIG-BVC for BSS Area */
1322private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1323{
1324 /* we expect the paging to arrive on all three NSE */
1325 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1326}
1327testcase TC_paging_ps_sig_bss() runs on test_CT {
1328 var BSSGP_ConnHdlr vc_conn;
1329 f_init();
1330
1331 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1332 vc_conn.done;
1333
1334 f_cleanup();
1335}
1336
1337/* PS-PAGING on SIG-BVC for Location Area */
1338private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1339{
1340 /* Both PCU index 0 and 1 have a BVC within the LAC */
1341 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1342}
1343testcase TC_paging_ps_sig_lac() runs on test_CT {
1344 var BSSGP_ConnHdlr vc_conn;
1345 f_init();
1346
1347 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1348 vc_conn.done;
1349
1350 f_cleanup();
1351}
1352
Harald Welte7462a592020-11-23 22:07:07 +01001353/* PS-PAGING on SIG-BVC for unknown Location Area */
1354private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1355{
1356 var GSM_Types.LocationAreaIdentification unknown_la := {
1357 mcc_mnc := '567F99'H,
1358 lac := 33333
1359 };
1360 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1361}
1362testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1363 var BSSGP_ConnHdlr vc_conn;
1364 f_init();
1365
1366 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1367 vc_conn.done;
1368
1369 f_cleanup();
1370}
1371
Harald Welte0e188242020-11-22 21:46:48 +01001372/* PS-PAGING on SIG-BVC for Routeing Area */
1373private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1374{
1375 /* Only PCU index 0 has a matching BVC within the LAC */
1376 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1377}
1378testcase TC_paging_ps_sig_rac() runs on test_CT {
1379 var BSSGP_ConnHdlr vc_conn;
1380 f_init();
1381
1382 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1383 vc_conn.done;
1384
1385 f_cleanup();
1386}
1387
Harald Welte7462a592020-11-23 22:07:07 +01001388/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1389private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1390{
1391 var RoutingAreaIdentification unknown_ra := {
1392 lai := {
1393 mcc_mnc := '567F99'H,
1394 lac := 33333
1395 },
1396 rac := 254
1397 };
1398 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1399}
1400testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1401 var BSSGP_ConnHdlr vc_conn;
1402 f_init();
1403
1404 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1405 vc_conn.done;
1406
1407 f_cleanup();
1408}
1409
Harald Welte0e188242020-11-22 21:46:48 +01001410/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1411private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1412{
1413 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1414}
1415testcase TC_paging_ps_sig_bvci() runs on test_CT {
1416 var BSSGP_ConnHdlr vc_conn;
1417 f_init();
1418
1419 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1420 vc_conn.done;
1421
1422 f_cleanup();
1423}
1424
Harald Welte7462a592020-11-23 22:07:07 +01001425/* PS-PAGING on SIG-BVC for unknown BVCI */
1426private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1427{
1428 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1429}
1430testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1431 var BSSGP_ConnHdlr vc_conn;
1432 f_init();
1433
1434 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1435 vc_conn.done;
1436
1437 f_cleanup();
1438}
1439
1440
Harald Welte0e188242020-11-22 21:46:48 +01001441
1442/***********************************************************************
1443 * PAGING CS procedure
1444 ***********************************************************************/
1445
1446private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1447 boolean use_sig := false)
1448runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1449 var template (value) PDU_BSSGP pdu_tx;
1450 var template (present) PDU_BSSGP pdu_rx;
1451 /* we always specify '0' as BVCI in the templates below, as we override it with
1452 * 'p4' later anyway */
1453 pdu_rx := tr_BSSGP_CS_PAGING(0);
1454 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1455 if (ispresent(g_pars.p_tmsi)) {
1456 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1457 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1458 } else {
1459 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1460 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1461 }
1462 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1463 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1464 if (use_sig == false) {
1465 SGSN[sgsn_idx].send(pdu_tx);
1466 } else {
1467 SGSN_SIG[sgsn_idx].send(pdu_tx);
1468 }
1469 return pdu_rx;
1470}
1471
1472/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1473 * specified PCU index */
1474private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1475 boolean use_sig := false,integer pcu_idx := 0)
1476runs on BSSGP_ConnHdlr {
1477 var template (present) PDU_BSSGP exp_rx;
1478 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1479 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1480 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1481 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1482 timer T := 2.0;
1483 T.start;
1484 alt {
1485 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1486 setverdict(pass);
1487 repeat;
1488 }
1489 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1490 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1491 }
1492 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1493 setverdict(pass);
1494 repeat;
1495 }
1496 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1497 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1498 }
1499 [] any from PCU.receive(exp_rx) {
1500 setverdict(fail, "Paging received on unexpected BVC");
1501 }
1502 [] any from PCU_SIG.receive(exp_rx) {
1503 setverdict(fail, "Paging received on unexpected BVC");
1504 }
1505 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1506 setverdict(fail, "Different Paging than expected received PTP BVC");
1507 }
1508 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1509 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1510 }
1511 [] T.timeout;
1512 }
1513}
1514
Harald Welte7462a592020-11-23 22:07:07 +01001515/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1516private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1517 boolean use_sig := false)
1518runs on BSSGP_ConnHdlr {
1519 var template (present) PDU_BSSGP exp_rx;
1520 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1521 /* Expect paging to propagate to no BSS */
1522 timer T := 2.0;
1523 T.start;
1524 alt {
1525 [] any from PCU.receive(exp_rx) {
1526 setverdict(fail, "Paging received on unexpected BVC");
1527 }
1528 [] any from PCU_SIG.receive(exp_rx) {
1529 setverdict(fail, "Paging received on unexpected BVC");
1530 }
1531 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1532 setverdict(fail, "Different Paging received on PTP BVC");
1533 }
1534 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1535 setverdict(fail, "Different Paging received on SIGNALING BVC");
1536 }
1537 [] T.timeout {
1538 setverdict(pass);
1539 }
1540 }
1541}
1542
Harald Welte0e188242020-11-22 21:46:48 +01001543private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1544{
1545 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1546 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1547 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1548}
1549testcase TC_paging_cs_ptp_bss() runs on test_CT {
1550 var BSSGP_ConnHdlr vc_conn;
1551 f_init();
1552
1553 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1554 vc_conn.done;
1555
1556 f_cleanup();
1557}
1558
1559/* CS-PAGING on PTP-BVC for Location Area */
1560private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1561{
1562 var template (present) PDU_BSSGP exp_rx;
1563 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1564 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1565 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1566}
1567testcase TC_paging_cs_ptp_lac() runs on test_CT {
1568 var BSSGP_ConnHdlr vc_conn;
1569 f_init();
1570
1571 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1572 vc_conn.done;
1573
1574 f_cleanup();
1575}
1576
Harald Welte7462a592020-11-23 22:07:07 +01001577/* CS-PAGING on PTP-BVC for unknown Location Area */
1578private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1579{
1580 var GSM_Types.LocationAreaIdentification unknown_la := {
1581 mcc_mnc := '567F99'H,
1582 lac := 33333
1583 };
1584 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1585 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1586}
1587testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1588 var BSSGP_ConnHdlr vc_conn;
1589 f_init();
1590
1591 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1592 vc_conn.done;
1593
1594 f_cleanup();
1595}
1596
Harald Welte0e188242020-11-22 21:46:48 +01001597/* CS-PAGING on PTP-BVC for Routeing Area */
1598private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1599{
1600 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1601 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1602 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1603}
1604testcase TC_paging_cs_ptp_rac() runs on test_CT {
1605 var BSSGP_ConnHdlr vc_conn;
1606 f_init();
1607
1608 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1609 vc_conn.done;
1610
1611 f_cleanup();
1612}
1613
Harald Welte7462a592020-11-23 22:07:07 +01001614/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1615private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1616{
1617 var RoutingAreaIdentification unknown_ra := {
1618 lai := {
1619 mcc_mnc := '567F99'H,
1620 lac := 33333
1621 },
1622 rac := 254
1623 };
1624 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1625 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1626}
1627testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1628 var BSSGP_ConnHdlr vc_conn;
1629 f_init();
1630
1631 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1632 vc_conn.done;
1633
1634 f_cleanup();
1635}
1636
Harald Welte0e188242020-11-22 21:46:48 +01001637/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1638private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1639{
1640 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1641 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1642}
1643testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1644 var BSSGP_ConnHdlr vc_conn;
1645 f_init();
1646
1647 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1648 vc_conn.done;
1649
1650 f_cleanup();
1651}
1652
Harald Welte7462a592020-11-23 22:07:07 +01001653/* CS-PAGING on PTP-BVC for unknown BVCI */
1654private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1655{
1656 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1657 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1658}
1659testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1660 var BSSGP_ConnHdlr vc_conn;
1661 f_init();
1662
1663 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1664 vc_conn.done;
1665
1666 f_cleanup();
1667}
1668
Harald Welte0e188242020-11-22 21:46:48 +01001669/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1670private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1671 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1672{
1673 var template (present) PDU_BSSGP exp_rx;
1674 exp_rx := f_send_paging_cs(p4, 0, true);
1675
1676 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1677 var ro_default defaults := {};
1678 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1679 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1680 defaults := defaults & { d };
1681 }
1682 f_sleep(2.0);
1683 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1684 deactivate(defaults[i]);
1685 }
1686 log("Paging received on PCU ", g_roi);
1687
1688 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1689 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1690 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1691 if (exp_on_i and not rx_on_i) {
1692 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1693 }
1694 if (not exp_on_i and rx_on_i) {
1695 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1696 }
1697 }
1698 setverdict(pass);
1699}
1700
1701/* CS-PAGING on SIG-BVC for BSS Area */
1702private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1703{
1704 /* we expect the paging to arrive on all three NSE */
1705 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1706}
1707testcase TC_paging_cs_sig_bss() runs on test_CT {
1708 var BSSGP_ConnHdlr vc_conn;
1709 f_init();
1710
1711 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1712 vc_conn.done;
1713
1714 f_cleanup();
1715}
1716
1717/* CS-PAGING on SIG-BVC for Location Area */
1718private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1719{
1720 /* Both PCU index 0 and 1 have a BVC within the LAC */
1721 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1722}
1723testcase TC_paging_cs_sig_lac() runs on test_CT {
1724 var BSSGP_ConnHdlr vc_conn;
1725 f_init();
1726
1727 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1728 vc_conn.done;
1729
1730 f_cleanup();
1731}
1732
Harald Welte7462a592020-11-23 22:07:07 +01001733/* CS-PAGING on SIG-BVC for unknown Location Area */
1734private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1735{
1736 var GSM_Types.LocationAreaIdentification unknown_la := {
1737 mcc_mnc := '567F99'H,
1738 lac := 33333
1739 };
1740 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1741}
1742testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1743 var BSSGP_ConnHdlr vc_conn;
1744 f_init();
1745
1746 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1747 vc_conn.done;
1748
1749 f_cleanup();
1750}
1751
Harald Welte0e188242020-11-22 21:46:48 +01001752/* CS-PAGING on SIG-BVC for Routeing Area */
1753private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1754{
1755 /* Only PCU index 0 has a matching BVC within the LAC */
1756 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1757}
1758testcase TC_paging_cs_sig_rac() runs on test_CT {
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
1761
1762 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1763 vc_conn.done;
1764
1765 f_cleanup();
1766}
1767
Harald Welte7462a592020-11-23 22:07:07 +01001768/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1769private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1770{
1771 var RoutingAreaIdentification unknown_ra := {
1772 lai := {
1773 mcc_mnc := '567F99'H,
1774 lac := 33333
1775 },
1776 rac := 254
1777 };
1778 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1779}
1780testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1781 var BSSGP_ConnHdlr vc_conn;
1782 f_init();
1783
1784 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1785 vc_conn.done;
1786
1787 f_cleanup();
1788}
1789
Harald Welte0e188242020-11-22 21:46:48 +01001790/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1791private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1792{
1793 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1794}
1795testcase TC_paging_cs_sig_bvci() runs on test_CT {
1796 var BSSGP_ConnHdlr vc_conn;
1797 f_init();
1798
1799 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1800 vc_conn.done;
1801
1802 f_cleanup();
1803}
1804
Harald Welte7462a592020-11-23 22:07:07 +01001805/* CS-PAGING on SIG-BVC for unknown BVCI */
1806private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1807{
1808 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1809}
1810testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1811 var BSSGP_ConnHdlr vc_conn;
1812 f_init();
1813
1814 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1815 vc_conn.done;
1816
1817 f_cleanup();
1818}
1819
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001820private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1821 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1822 var integer i;
1823 for (i := 0; i < 10; i := i+1) {
1824 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1825 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1826 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1827
1828 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1829
1830 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1831 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1832 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1833
1834 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1835 }
1836 setverdict(pass);
1837}
1838testcase TC_flush_ll() runs on test_CT
1839{
1840 var BSSGP_ConnHdlr vc_conn;
1841 f_init();
1842
1843 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1844 vc_conn.done;
1845 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1846
1847 f_cleanup();
1848}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001849
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001850private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1851runs on GlobalTest_CT {
1852[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1853 if (ro_integer_contains(roi, pcu_idx)) {
1854 setverdict(fail, "Received multiple on same SIG BVC");
1855 }
1856 roi := roi & { pcu_idx };
1857 repeat;
1858 }
1859}
1860/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1861testcase TC_trace() runs on GlobalTest_CT
1862{
1863 var BSSGP_ConnHdlr vc_conn;
1864 f_init();
1865 f_global_init();
1866
1867 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1868 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1869
1870 var ro_default defaults := {};
1871 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1872 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1873 }
1874 G_SGSN[0].send(pdu_tx);
1875 f_sleep(2.0);
1876 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1877 deactivate(defaults[i]);
1878 }
1879
1880 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1881 if (not ro_integer_contains(g_roi, i)) {
1882 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
1883 }
1884 }
1885 setverdict(pass);
1886
1887 f_cleanup();
1888}
1889
Harald Weltec0351d12020-11-27 22:49:02 +01001890private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
1891 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1892
1893 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
1894 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1895 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
1896
1897 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1898
1899 setverdict(pass);
1900}
1901/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
1902testcase TC_llc_discarded() runs on test_CT
1903{
1904 var BSSGP_ConnHdlr vc_conn;
1905 f_init();
1906
1907 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
1908 vc_conn.done;
1909 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1910
1911 f_cleanup();
1912}
1913
Harald Weltef20af412020-11-28 16:11:11 +01001914/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
1915testcase TC_overload() runs on GlobalTest_CT
1916{
1917 f_init();
1918 f_global_init();
1919
1920 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
1921 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
1922
1923 var ro_default defaults := {};
1924 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1925 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1926 }
1927 G_SGSN[0].send(pdu_tx);
1928 f_sleep(2.0);
1929 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1930 deactivate(defaults[i]);
1931 }
1932
1933 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1934 if (not ro_integer_contains(g_roi, i)) {
1935 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
1936 }
1937 }
1938 setverdict(pass);
1939
1940 f_cleanup();
1941}
1942
Harald Welte239aa502020-11-24 23:14:20 +01001943private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1944{
1945 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1946 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1947 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1948
1949 SGSN_MGMT.clear;
1950 PCU_MGMT.clear;
1951
1952 /* block the PTP BVC from the PCU side */
1953 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
1954 /* expect state on both PCU and SGSN side to change */
1955 interleave {
1956 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
1957 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
1958 }
1959 setverdict(pass);
1960}
1961testcase TC_bvc_block_ptp() runs on test_CT
1962{
1963 f_init();
1964 f_sleep(1.0);
1965 f_block_ptp_bvc_from_pcu(0, 0);
1966 f_cleanup();
1967}
1968
1969private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1970{
1971 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1972 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1973 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1974
1975 SGSN_MGMT.clear;
1976 PCU_MGMT.clear;
1977
1978 /* block the PTP BVC from the PCU side */
1979 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
1980 /* expect state on both PCU and SGSN side to change */
1981 interleave {
1982 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
1983 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
1984 }
1985 setverdict(pass);
1986}
1987testcase TC_bvc_unblock_ptp() runs on test_CT
1988{
1989 f_init();
1990 f_sleep(1.0);
1991 f_block_ptp_bvc_from_pcu(0, 0);
1992 f_sleep(1.0);
1993 f_unblock_ptp_bvc_from_pcu(0, 0);
1994 f_cleanup();
1995}
1996
Harald Welte60a8ec72020-11-25 17:12:53 +01001997private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
1998[] pt.receive(BssgpStatusIndication:?) { repeat; }
1999}
2000private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2001 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2002 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2003 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2004 }
2005 }
2006 return null;
2007}
2008private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2009{
2010 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2011 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2012 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2013 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2014 var default d;
2015
2016 SGSN_MGMT.clear;
2017 PCU_MGMT.clear;
2018
2019 /* block the PTP BVC from the PCU side */
2020 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2021 /* expect state on both PCU and SGSN side to change */
2022 d := activate(as_ignore_status(SGSN_MGMT));
2023 interleave {
2024 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2025 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2026 }
2027 deactivate(d);
2028 setverdict(pass);
2029}
2030/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2031testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2032{
2033 f_init();
2034 f_sleep(3.0);
2035 f_reset_ptp_bvc_from_pcu(0, 0);
2036 f_cleanup();
2037}
2038
Harald Welte16786e92020-11-27 19:11:56 +01002039private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2040runs on test_CT {
2041 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2042 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2043 roi := roi & { bvci };
2044 }
2045}
2046/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2047testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2048
2049 f_init();
2050 f_sleep(3.0);
2051
2052 /* Start BVC-RESET procedure for BVCI=0 */
2053 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2054
2055 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2056 var ro_default defaults := {};
2057 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2058 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2059 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2060 defaults := defaults & { d };
2061 }
2062
2063 timer T := 3.0;
2064 T.start;
2065 alt {
2066 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2067 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2068 }
2069 [] T.timeout;
2070 }
2071
2072 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2073 deactivate(defaults[i]);
2074 }
2075
2076 /* check if BVC-block was received on all expected BVC */
2077 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2078 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2079 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2080 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2081 }
2082 }
2083
2084 /* check if BVC-block was not received on any unexpected BVC is not required as
2085 * such a message would basically run into 'no matching clause' */
2086
2087 f_cleanup();
2088}
2089
Harald Welte60a8ec72020-11-25 17:12:53 +01002090private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2091{
2092 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2093 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2094 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2095 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2096 var default d;
2097
2098 SGSN_MGMT.clear;
2099 PCU_MGMT.clear;
2100
2101 /* block the PTP BVC from the PCU side */
2102 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2103 /* expect state on both PCU and SGSN side to change */
2104 d := activate(as_ignore_status(PCU_MGMT));
2105 interleave {
2106 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2107 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2108 }
2109 deactivate(d);
2110 setverdict(pass);
2111}
2112/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2113testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2114{
2115 f_init();
2116 f_sleep(3.0);
2117 f_reset_ptp_bvc_from_sgsn(0, 0);
2118 f_cleanup();
2119}
2120
Harald Welte16786e92020-11-27 19:11:56 +01002121private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2122runs on test_CT {
2123 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2124 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2125 roi := roi & { nsei };
2126 }
2127}
2128/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2129testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2130
2131 f_init();
2132 f_sleep(3.0);
2133
2134 /* Start BVC-RESET procedure for BVCI=0 */
2135 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2136
2137 /* Activate altsteps: One for each PCU NSE */
2138 var ro_default defaults := {};
2139 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2140 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2141 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2142 defaults := defaults & { d };
2143 }
2144
2145 f_sleep(3.0);
2146
2147 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2148 deactivate(defaults[i]);
2149 }
2150
2151 /* check if BVC-block was received on all expected BVC */
2152 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2153 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2154 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2155 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2156 }
2157 }
2158
2159 /* check if BVC-block was not received on any unexpected BVC is not required as
2160 * such a message would basically run into 'no matching clause' */
2161
2162 f_cleanup();
2163}
2164
Daniel Willmann423d8f42020-09-08 18:58:22 +02002165control {
2166 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002167 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002168 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002169 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002170 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002171 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002172 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002173 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002174 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002175 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002176 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002177 execute( TC_bvc_block_ptp() );
2178 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002179 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002180 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002181 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002182 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef8ef0282020-11-18 12:16:59 +01002183 if (false) {
2184 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2185 execute( TC_load_sharing_dl() );
2186 }
Harald Welte0e188242020-11-22 21:46:48 +01002187
2188 /* PAGING-PS over PTP BVC */
2189 execute( TC_paging_ps_ptp_bss() );
2190 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002191 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002192 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002193 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002194 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002195 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002196
2197 /* PAGING-PS over SIG BVC */
2198 execute( TC_paging_ps_sig_bss() );
2199 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002200 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002201 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002202 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002203 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002204 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002205
2206 /* PAGING-CS over PTP BVC */
2207 execute( TC_paging_cs_ptp_bss() );
2208 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002209 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002210 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002211 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002212 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002213 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002214
2215 /* PAGING-CS over SIG BVC */
2216 execute( TC_paging_cs_sig_bss() );
2217 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002218 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002219 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002220 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002221 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002222 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002223
2224
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002225 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002226}
2227
2228
2229}