blob: 62daaf41d28ce3393fa3e20001c91898e4e08191 [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;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010017import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020018import from GSM_Types all;
19import from Native_Functions all;
20import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
24import from SCCPasp_Types all;
25import from Osmocom_Gb_Types all;
26
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
36import from LLC_Types all;
37import from LLC_Templates all;
38
39import from GSM_RR_Types all;
40
Harald Welte6d63f742020-11-15 19:44:04 +010041/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
42const BcdMccMnc c_mcc_mnc := '262F42'H;
43
Harald Welte0d5fceb2020-11-29 16:04:07 +010044/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
45const integer max_fr_info_size := 1600;
46
Daniel Willmann423d8f42020-09-08 18:58:22 +020047modulepar {
Harald Weltef6e59b02020-12-08 08:29:09 +010048 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010049 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010050 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020051 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020052 nsei := 101,
53 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010054 handle_sns := false,
55 nsvc := {
56 {
57 provider := {
58 ip := {
59 address_family := AF_INET,
60 local_udp_port := 7777,
61 local_ip := "127.0.0.1",
62 remote_udp_port := 23000,
63 remote_ip := "127.0.0.1"
64 }
65 },
66 nsvci := 101
67 }
68 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020069 }
70 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010071 /* BSS NSEI start at 2000 + x
72 * NSVCI start from value of NSEI + 100
73 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010074 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020075 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010076 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +020077 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010078 handle_sns := false,
79 nsvc := {
80 {
81 provider := {
82 ip := {
83 address_family := AF_INET,
84 local_udp_port := 21010,
85 local_ip := "127.0.0.1",
86 remote_udp_port := 23000,
87 remote_ip := "127.0.0.1"
88 }
89 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +010090 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +010091 }
92 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020093 },
94 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010095 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +020096 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010097 handle_sns := false,
98 nsvc := {
99 {
100 provider := {
101 ip := {
102 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100103 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100104 local_ip := "127.0.0.1",
105 remote_udp_port := 23000,
106 remote_ip := "127.0.0.1"
107 }
108 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100109 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100110 }
111 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200112 },
113 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100114 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200115 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100116 handle_sns := false,
117 nsvc := {
118 {
119 provider := {
120 ip := {
121 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100122 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100123 local_ip := "127.0.0.1",
124 remote_udp_port := 23000,
125 remote_ip := "127.0.0.1"
126 }
127 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100128 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100129 }
130 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200131 }
132 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100133 /* BVCI are NSEI*10 + x
134 * The first NSE only has one BVC, the second one 2 and so on
135 * The Cell ID is BVCI + 10000
136 * LAC/RAC are configured in such a way that:
137 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
138 * LAC 13300 is present twice in NSE(2003)
139 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
140 * RAI 13300-0 is present twice in NSE(2003)
141 */
Harald Welte6d63f742020-11-15 19:44:04 +0100142 BssgpConfigs mp_gbconfigs := {
143 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100144 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100145 sgsn_role := false,
146 bvc := {
147 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100148 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100149 cell_id := {
150 ra_id := {
151 lai := {
152 mcc_mnc := c_mcc_mnc,
153 lac := 13135
154 },
155 rac := 0
156 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100157 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100158 },
159 depth := BSSGP_DECODE_DEPTH_BSSGP,
160 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
161 }
162 }
163 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100165 sgsn_role := false,
166 bvc := {
167 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100168 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100169 cell_id := {
170 ra_id := {
171 lai := {
172 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100173 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100174 },
Harald Welte0e188242020-11-22 21:46:48 +0100175 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100176 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100177 cell_id := 30021
178 },
179 depth := BSSGP_DECODE_DEPTH_BSSGP,
180 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
181 },
182 {
183 bvci := 20022,
184 cell_id := {
185 ra_id := {
186 lai := {
187 mcc_mnc := c_mcc_mnc,
188 lac := 13135
189 },
190 rac := 2
191 },
192 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100193 },
194 depth := BSSGP_DECODE_DEPTH_BSSGP,
195 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
196 }
197 }
198 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100199 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100200 sgsn_role := false,
201 bvc := {
202 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100203 bvci := 20031,
204 cell_id := {
205 ra_id := {
206 lai := {
207 mcc_mnc := c_mcc_mnc,
208 lac := 13135
209 },
210 rac := 1
211 },
212 cell_id := 30031
213 },
214 depth := BSSGP_DECODE_DEPTH_BSSGP,
215 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
216 },
217 {
218 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100219 cell_id := {
220 ra_id := {
221 lai := {
222 mcc_mnc := c_mcc_mnc,
223 lac := 13300
224 },
225 rac := 0
226 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100227 cell_id := 30032
228 },
229 depth := BSSGP_DECODE_DEPTH_BSSGP,
230 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
231 },
232 {
233 bvci := 20033,
234 cell_id := {
235 ra_id := {
236 lai := {
237 mcc_mnc := c_mcc_mnc,
238 lac := 13300
239 },
240 rac := 0
241 },
242 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100243 },
244 depth := BSSGP_DECODE_DEPTH_BSSGP,
245 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
246 }
247 }
248 }
249 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200250};
251
Daniel Willmann423d8f42020-09-08 18:58:22 +0200252type record GbInstance {
253 NS_CT vc_NS,
254 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100255 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200256 BssgpConfig cfg
257};
Harald Welte67dc8c22020-11-17 18:32:29 +0100258type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200259
260const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100261type record of GbInstance GbInstances;
262type record of BssgpConfig BssgpConfigs;
263type record of NSConfiguration NSConfigurations;
264type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200265
266const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200267
268type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100269 var GbInstances g_pcu;
270 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200271
272 port BSSGP_CT_PROC_PT PROC;
273
Harald Weltefbae83f2020-11-15 23:25:55 +0100274 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
275 port BSSGP_BVC_MGMT_PT PCU_MGMT;
276
Daniel Willmann423d8f42020-09-08 18:58:22 +0200277 port TELNETasp_PT GBPVTY;
278
279 var boolean g_initialized := false;
280 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100281
282 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100283 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200284};
285
286type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100287 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100288 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200289 port BSSGP_PT PCU_SIG[NUM_PCU];
290 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100291 /* component reference to the component to which we're currently connected */
292 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100293 /* BSSGP BVC configuration of the component to which we're currently connected */
294 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100295
296 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100297 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200298 port BSSGP_PT SGSN_SIG[NUM_SGSN];
299 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100300 /* component reference to the component to which we're currently connected */
301 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302
303 var BSSGP_ConnHdlrPars g_pars;
304 timer g_Tguard;
305 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100306
307 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200308}
309
310type record SGSN_ConnHdlrNetworkPars {
311 boolean expect_ptmsi,
312 boolean expect_auth,
313 boolean expect_ciph
314};
315
316type record BSSGP_ConnHdlrPars {
317 /* IMEI of the simulated ME */
318 hexstring imei,
319 /* IMSI of the simulated MS */
320 hexstring imsi,
321 /* MSISDN of the simulated MS (probably unused) */
322 hexstring msisdn,
323 /* P-TMSI allocated to the simulated MS */
324 OCT4 p_tmsi optional,
325 OCT3 p_tmsi_sig optional,
326 /* TLLI of the simulated MS */
327 OCT4 tlli,
328 OCT4 tlli_old optional,
329 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100330 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100331 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200332 float t_guard
333};
334
335private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
336 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
337 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
338
339 var RoutingAreaIdentificationV ret := {
340 mccDigit1 := mcc_mnc[0],
341 mccDigit2 := mcc_mnc[1],
342 mccDigit3 := mcc_mnc[2],
343 mncDigit3 := mcc_mnc[3],
344 mncDigit1 := mcc_mnc[4],
345 mncDigit2 := mcc_mnc[5],
346 lac := int2oct(cell_id.ra_id.lai.lac, 16),
347 rac := int2oct(cell_id.ra_id.rac, 8)
348 }
349 return ret;
350};
351
Harald Welte95339432020-12-02 18:50:52 +0100352private function f_fix_create_cb(inout BssgpConfig cfg)
353{
354 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
355 if (not isbound(cfg.bvc[i].create_cb)) {
356 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
357 }
358 }
359}
360
Daniel Willmann423d8f42020-09-08 18:58:22 +0200361private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100362 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
363 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
364 gb.vc_NS := NS_CT.create(ns_id);
365 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200366 /* connect lower end of BSSGP emulation with NS upper port */
367 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
368
Harald Welteb419d0e2020-11-16 16:45:05 +0100369 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
370 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200371
372 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
373 connect(self:PROC, gb.vc_BSSGP:PROC);
374 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
375 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100376 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200377 }
Harald Welte16786e92020-11-27 19:11:56 +0100378 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200379}
380
381private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100382 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
383 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
384 gb.vc_NS := NS_CT.create(ns_id);
385 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200386 /* connect lower end of BSSGP emulation with NS upper port */
387 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
388
Harald Welteb419d0e2020-11-16 16:45:05 +0100389 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
390 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200391
392 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
393 connect(self:PROC, gb.vc_BSSGP:PROC);
394 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
395 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100396 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397 }
Harald Welte16786e92020-11-27 19:11:56 +0100398 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200399}
400
401
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100402private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
403 gb.vc_NS.stop;
404 gb.vc_BSSGP.stop;
405
406 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
407 gb.vc_BSSGP_BVC[i].stop;
408 }
409}
410
Daniel Willmann423d8f42020-09-08 18:58:22 +0200411private function f_init_vty() runs on test_CT {
412 map(self:GBPVTY, system:GBPVTY);
413 f_vty_set_prompts(GBPVTY);
414 f_vty_transceive(GBPVTY, "enable");
415}
416
Harald Weltefbae83f2020-11-15 23:25:55 +0100417type record of integer ro_integer;
418
419private function ro_integer_contains(ro_integer r, integer x) return boolean {
420 for (var integer j := 0; j < lengthof(r); j := j+1) {
421 if (r[j] == x) {
422 return true;
423 }
424 }
425 return false;
426}
427
Harald Welte425d3762020-12-09 14:33:18 +0100428function f_init(float t_guard := 30.0) runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100429 var ro_integer bvci_unblocked := {};
430 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200431 var integer i;
432
433 if (g_initialized == true) {
434 return;
435 }
436 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200437
Harald Welte425d3762020-12-09 14:33:18 +0100438 g_Tguard.start(t_guard);
439 activate(as_gTguard(g_Tguard));
440
Daniel Willmann423d8f42020-09-08 18:58:22 +0200441 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100442 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200443 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100444 bvc := { }
445 }
446 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
447 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100448 /* make sure all have a proper crate_cb, which cannot be specified in config file */
449 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100450 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welte95339432020-12-02 18:50:52 +0100451 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & g_pcu[i].cfg.bvc;
Harald Welte6d63f742020-11-15 19:44:04 +0100452 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200453
454 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100455 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100456 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100457 }
458 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
459 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
460 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
461 }
462
463 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100464 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100465 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200466 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100467 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100468 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100469 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100470
471 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100472 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100473 T.start;
474 alt {
475 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
476 bvci_unblocked := bvci_unblocked & { bsi.bvci };
477 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
478 repeat;
479 }
480 }
481 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
482 repeat;
483 }
Harald Welte3c905152020-11-26 20:56:09 +0100484 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
485 repeat;
486 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100487 [] SGSN_MGMT.receive {
488 setverdict(fail, "Received unexpected message on SGSN_MGMT");
489 mtc.stop;
490 }
491
492 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
493 repeat;
494 }
495 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
496 repeat;
497 }
498 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
499 repeat;
500 }
501 [] PCU_MGMT.receive {
502 setverdict(fail, "Received unexpected message on PCU_MGMT");
503 mtc.stop;
504 }
505
506 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100507 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
508 "unblocked so far: ", bvci_unblocked, "expected: ", g_sgsn[0].cfg.bvc);
509 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100510 }
511 }
512
513 /* iterate over list and check all BVCI */
514 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
515 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
516 if (not ro_integer_contains(bvci_unblocked, bvci)) {
517 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
518 mtc.stop;
519 }
520 }
Harald Welte425d3762020-12-09 14:33:18 +0100521
522 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
523 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200524}
525
526function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100527 var integer i;
528
Daniel Willmann491af2a2021-01-08 01:32:51 +0100529 /* To avoid a dynamic test case error we need to prevent messages arriving on unconnected
530 * ports. Waiting here ensures that any messages "in flight" will be delivered to the port
531 * before the component is shutdown and disconnected. */
532 f_sleep(0.2);
533
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100534 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
535 f_destroy_gb(g_sgsn[i]);
536 }
537 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
538 f_destroy_gb(g_pcu[i]);
539 }
540
541 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200542}
543
544type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
545
546/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100547function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200548 float t_guard := 30.0)
549runs on test_CT return BSSGP_ConnHdlr {
550 var BSSGP_ConnHdlr vc_conn;
551
552 var BSSGP_ConnHdlrPars pars := {
553 imei := f_gen_imei(imsi_suffix),
554 imsi := f_gen_imsi(imsi_suffix),
555 msisdn := f_gen_msisdn(imsi_suffix),
556 p_tmsi := omit,
557 p_tmsi_sig := omit,
558 tlli := f_gprs_tlli_random(),
559 tlli_old := omit,
560 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100561 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100562 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200563 t_guard := t_guard
564 };
565
566 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200567
568 vc_conn.start(f_handler_init(fn, id, pars));
569 return vc_conn;
570}
571
Harald Welte3dd21b32020-11-17 19:21:00 +0100572/* 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 +0100573private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
574runs on BSSGP_ConnHdlr {
575 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100576 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100577 /* unregister + disconnect from old BVC */
578 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100579 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100580 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
581 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
582 }
583 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100584 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100585 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
586 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
587 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
588 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100589 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100590}
591
592/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
593private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
Harald Welte158becf2020-12-09 12:32:32 +0100594 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100595 /* unregister + disconnect from old BVC */
596 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100597 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100598 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
599 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
600 }
601 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100602 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100603 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
604 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
605 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
606 sgsn_ct[port_idx] := bvc_ct;
607}
608
Harald Welte425d3762020-12-09 14:33:18 +0100609private altstep as_gTguard(timer Tguard) {
610 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200611 setverdict(fail, "Tguard timeout");
612 mtc.stop;
613 }
614}
615
616/* first function called in every ConnHdlr */
617private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
618runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100619 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200620 /* do some common stuff like setting up g_pars */
621 g_pars := pars;
622
623 llc := f_llc_create(false);
624
Harald Welte3dd21b32020-11-17 19:21:00 +0100625 /* default connections on PCU side: First BVC of each NSE/PCU */
626 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100627 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100628 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100629
630 /* default connections on SGSN side: First BVC of each NSE/SGSN */
631 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
632 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100633 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200634
635 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100636 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200637
638 /* call the user-supplied test case function */
639 fn.apply(id);
640}
641
Harald Welte1e834f32020-11-15 20:02:59 +0100642private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
643runs on BSSGP_ConnHdlr {
644 PT.call(BSSGP_register_client:{imsi, tlli}) {
645 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
646 }
647}
648
649private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
650runs on BSSGP_ConnHdlr {
651 PT.call(BSSGP_unregister_client:{imsi}) {
652 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
653 }
654}
655
Harald Welte22ef5d92020-11-16 13:35:14 +0100656/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
657friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100658 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100659 var PDU_BSSGP rx;
660 timer T := 1.0;
661
Daniel Willmann4798fd72020-11-24 16:23:29 +0100662 if (use_sig) {
663 PCU_SIG[pcu_idx].send(tx);
664 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100665 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100666 }
667
Harald Welte22ef5d92020-11-16 13:35:14 +0100668 T.start;
669 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100670 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
671 setverdict(pass);
672 }
Harald Welte158becf2020-12-09 12:32:32 +0100673 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100674 setverdict(pass);
675 }
Harald Welte158becf2020-12-09 12:32:32 +0100676 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100677 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
678 mtc.stop;
679 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100680 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
681 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
682 mtc.stop;
683 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100684 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100685 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100686 mtc.stop;
687 }
688 }
689}
690
691/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
692friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100693 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100694 var PDU_BSSGP rx;
695 timer T := 1.0;
696
Daniel Willmann4798fd72020-11-24 16:23:29 +0100697 if (use_sig) {
698 SGSN_SIG[sgsn_idx].send(tx);
699 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100700 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100701 }
702
Harald Welte22ef5d92020-11-16 13:35:14 +0100703 T.start;
704 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100705 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
706 setverdict(pass);
707 }
Harald Welte158becf2020-12-09 12:32:32 +0100708 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100709 setverdict(pass);
710 }
Harald Welte158becf2020-12-09 12:32:32 +0100711 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100712 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
713 mtc.stop;
714 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100715 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
716 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
717 mtc.stop;
718 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100719 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100720 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100721 mtc.stop;
722 }
723 }
724}
Harald Welte1e834f32020-11-15 20:02:59 +0100725
Harald Welte3807ed12020-11-24 19:05:22 +0100726/***********************************************************************
727 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
728 ***********************************************************************/
729
730type component GlobalTest_CT extends test_CT {
731 port BSSGP_PT G_PCU[NUM_PCU];
732 port BSSGP_PT G_SGSN[NUM_SGSN];
733};
734
Harald Welte299aa482020-12-09 15:10:55 +0100735/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100736private function f_global_init() runs on GlobalTest_CT {
737 var integer i;
738 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
739 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
740 }
741 for (i := 0; i < lengthof(g_pcu); i := i+1) {
742 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
743 }
744}
745
Harald Welte299aa482020-12-09 15:10:55 +0100746/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
747private function f_global_init_ptp() runs on GlobalTest_CT {
748 var integer i;
749 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
750 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
751 }
752 for (i := 0; i < lengthof(g_pcu); i := i+1) {
753 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
754 }
755}
756
Harald Welte3807ed12020-11-24 19:05:22 +0100757/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
758friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
759 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
760 var PDU_BSSGP rx;
761 timer T := 1.0;
762
763 G_PCU[pcu_idx].send(tx);
764 T.start;
765 alt {
766 [] G_SGSN[sgsn_idx].receive(exp_rx) {
767 setverdict(pass);
768 }
769 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
770 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
771 mtc.stop;
772 }
773 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100774 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100775 mtc.stop;
776 }
777 }
778}
779
780/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
781friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
782 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
783 var PDU_BSSGP rx;
784 timer T := 1.0;
785
786 G_SGSN[sgsn_idx].send(tx);
787 T.start;
788 alt {
789 [] G_PCU[pcu_idx].receive(exp_rx) {
790 setverdict(pass);
791 }
792 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
793 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
794 mtc.stop;
795 }
796 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100797 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100798 mtc.stop;
799 }
800 }
801}
802
803
Daniel Willmann423d8f42020-09-08 18:58:22 +0200804/* TODO:
805 * Detach without Attach
806 * SM procedures without attach / RAU
807 * ATTACH / RAU
808 ** with / without authentication
809 ** with / without P-TMSI allocation
810 * re-transmissions of LLC frames
811 * PDP Context activation
812 ** with different GGSN config in SGSN VTY
813 ** with different PDP context type (v4/v6/v46)
814 ** timeout from GGSN
815 ** multiple / secondary PDP context
816 */
817
818private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
819 f_sleep(5.0);
820 setverdict(pass);
821}
822
823testcase TC_BVC_bringup() runs on test_CT {
824 var BSSGP_ConnHdlr vc_conn;
825 f_init();
826
827 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
828 vc_conn.done;
829
830 f_cleanup();
831}
832
833friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100834 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200835 timer T := 5.0;
836 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100837 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200838 T.start;
839 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100840 [] 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 +0200841 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
842 }
Harald Welte16357a92020-11-17 18:20:00 +0100843 [] 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 +0200844 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
845 mtc.stop;
846 }
847 [] T.timeout {
848 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
849 mtc.stop;
850 }
851 }
852 return '00'O;
853}
854
855friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100856 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200857 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100858 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 +0200859 T.start;
860 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100861 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
862 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200863 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
864 mtc.stop;
865 }
866 [] T.timeout {
867 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
868 mtc.stop;
869 }
870 }
871}
872
873
Harald Welte92686012020-11-15 21:45:49 +0100874/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
875private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100876 var integer ran_idx := 0;
877 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100878 var integer i;
879
Harald Welte0d5fceb2020-11-29 16:04:07 +0100880 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100881 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100882 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 +0100883 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100884 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 +0100885
Harald Welte0d5fceb2020-11-29 16:04:07 +0100886 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100887 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100888 }
889 setverdict(pass);
890}
891
892testcase TC_ul_unitdata() runs on test_CT
893{
894 var BSSGP_ConnHdlr vc_conn;
895 f_init();
896
897 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
898 vc_conn.done;
899 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
900
901 f_cleanup();
902}
903
Harald Welte78d8db92020-11-15 23:27:27 +0100904/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
905private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
906 var integer i;
907
Harald Welte0d5fceb2020-11-29 16:04:07 +0100908 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100909 var octetstring payload := f_rnd_octstring(i);
910 var template (value) PDU_BSSGP pdu_tx :=
911 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
912 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
913 var template (present) PDU_BSSGP pdu_rx :=
914 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
915
Harald Welte0d5fceb2020-11-29 16:04:07 +0100916 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100917 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100918 }
919 setverdict(pass);
920}
921
922testcase TC_dl_unitdata() runs on test_CT
923{
924 var BSSGP_ConnHdlr vc_conn;
925 f_init();
926
927 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
928 vc_conn.done;
929 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
930
931 f_cleanup();
932}
Harald Welte92686012020-11-15 21:45:49 +0100933
Harald Welte6dc2ac42020-11-16 09:16:17 +0100934private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
935 var integer i;
936
937 for (i := 0; i < 10; i := i+1) {
938 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
939 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
940 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
941
Harald Welte22ef5d92020-11-16 13:35:14 +0100942 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100943 }
944 setverdict(pass);
945}
946testcase TC_ra_capability() runs on test_CT
947{
948 var BSSGP_ConnHdlr vc_conn;
949 f_init();
950
951 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
952 vc_conn.done;
953 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
954
955 f_cleanup();
956}
957
Daniel Willmannace3ece2020-11-16 19:53:26 +0100958private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
959 var integer i;
960 var OCT1 tag;
961 for (i := 0; i < 10; i := i+1) {
962 tag := int2oct(23 + i, 1);
963 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
964 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
965 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
966
967 f_pcu2sgsn(pdu_tx, pdu_rx);
968
969 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
970 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
971 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
972
973 f_sgsn2pcu(pdu_tx, pdu_rx);
974 }
975 setverdict(pass);
976}
977testcase TC_ra_capability_upd() runs on test_CT
978{
979 var BSSGP_ConnHdlr vc_conn;
980 f_init();
981
Daniel Willmann54833f22020-11-19 15:43:52 +0100982 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100983 vc_conn.done;
984 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
985
986 f_cleanup();
987}
988
Daniel Willmann165d6612020-11-19 14:27:29 +0100989private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
990 var integer i;
991 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
992 for (i := 0; i < 10; i := i+1) {
993 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
994 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
995 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
996
997 f_pcu2sgsn(pdu_tx, pdu_rx);
998 }
999 setverdict(pass);
1000}
1001testcase TC_radio_status() runs on test_CT
1002{
1003 var BSSGP_ConnHdlr vc_conn;
1004 f_init();
1005
Daniel Willmann54833f22020-11-19 15:43:52 +01001006 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001007 vc_conn.done;
1008 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1009
1010 f_cleanup();
1011}
1012
Harald Welte3807ed12020-11-24 19:05:22 +01001013private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001014 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001015
Daniel Willmannfa67f492020-11-19 15:48:05 +01001016 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001017 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001018 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001019 var OCT4 tlli := f_gprs_tlli_random();
1020 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001021 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001022 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001023
Harald Welte3807ed12020-11-24 19:05:22 +01001024 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001025
Harald Welte3807ed12020-11-24 19:05:22 +01001026 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001027 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001028 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001029
Harald Welte3807ed12020-11-24 19:05:22 +01001030 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001031
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001032 pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
1033 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1034 pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
1035
1036 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1037
Daniel Willmannfa67f492020-11-19 15:48:05 +01001038 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001039 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001040 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001041 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001042
Harald Welte3807ed12020-11-24 19:05:22 +01001043 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001044 }
1045 setverdict(pass);
1046}
Harald Welte3807ed12020-11-24 19:05:22 +01001047testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001048{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001049 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001050 f_global_init();
1051 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001052 f_cleanup();
1053}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001054
Harald Welte3807ed12020-11-24 19:05:22 +01001055private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001056 var integer i;
1057
1058 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001059 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001060 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001061 var OCT4 tlli := f_gprs_tlli_random();
1062 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001063 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001064 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001065
Harald Welte3807ed12020-11-24 19:05:22 +01001066 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001067
Harald Welte3807ed12020-11-24 19:05:22 +01001068 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001069 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001070 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001071
Harald Welte3807ed12020-11-24 19:05:22 +01001072 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001073
Daniel Willmann4c534bb2021-01-07 18:05:10 +01001074 pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1075 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1076 pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
1077
1078 f_global_pcu2sgsn(pdu_tx, pdu_rx);
1079
Daniel Willmann087a33d2020-11-19 15:58:43 +01001080 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001081 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001082 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001083 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001084
Harald Welte3807ed12020-11-24 19:05:22 +01001085 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001086 }
1087 setverdict(pass);
1088}
Harald Welte3807ed12020-11-24 19:05:22 +01001089testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001090{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001091 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001092 f_global_init();
1093 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001094 f_cleanup();
1095}
1096
Harald Weltef8ef0282020-11-18 12:16:59 +01001097/* test the load-sharing between multiple NS-VC on the BSS side */
1098private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1099 var integer i;
1100
1101 for (i := 0; i < 10; i := i+1) {
1102 var octetstring payload := f_rnd_octstring(i);
1103 var template (value) PDU_BSSGP pdu_tx :=
1104 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001105 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001106 }
1107 setverdict(pass);
1108}
1109testcase TC_load_sharing_dl() runs on test_CT_NS
1110{
1111 const integer num_ue := 10;
1112 var BSSGP_ConnHdlr vc_conn[num_ue];
1113 f_init();
1114
1115 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1116 * side so we get the raw NsUnitdataIndication and hence observe different
1117 * NSVCI */
1118 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1119 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1120
1121 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1122 * of the NS-VC is ALIVE/UNBLOCKED */
1123 f_sleep(3.0);
1124
1125 /* start parallel components generating DL-UNITDATA from the SGSN side */
1126 for (var integer i:= 0; i < num_ue; i := i+1) {
1127 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1128 }
1129
1130 /* now start counting all the messages that were queued before */
1131 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1132 var ro_integer rx_count := { 0, 0, 0, 0 };
1133 timer T := 2.0;
1134 T.start;
1135 alt {
1136 [] as_NsUdiCount(0, rx_count);
1137 [] as_NsUdiCount(1, rx_count);
1138 [] as_NsUdiCount(2, rx_count);
1139 [] as_NsUdiCount(3, rx_count);
1140 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1141 [] NS.receive(NsStatusIndication:?) { repeat; }
1142 [] NS.receive {
1143 setverdict(fail, "Rx unexpected NS");
1144 mtc.stop;
1145 }
1146 [] T.timeout {
1147 }
1148 }
1149 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1150 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1151 if (rx_count[i] == 0) {
1152 setverdict(fail, "Data not shared over all NSVC");
1153 }
1154 }
1155 setverdict(pass);
1156}
1157private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1158 var NsUnitdataIndication udi;
1159 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1160 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1161 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1162 repeat;
1163 }
1164}
1165type component test_CT_NS extends test_CT {
1166 port NS_PT NS;
1167};
1168
1169
Harald Welte0e188242020-11-22 21:46:48 +01001170/***********************************************************************
1171 * PAGING PS procedure
1172 ***********************************************************************/
1173
1174private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1175 boolean use_sig := false)
1176runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1177 var template (value) PDU_BSSGP pdu_tx;
1178 var template (present) PDU_BSSGP pdu_rx;
1179 /* we always specify '0' as BVCI in the templates below, as we override it with
1180 * 'p4' later anyway */
1181 pdu_rx := tr_BSSGP_PS_PAGING(0);
1182 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1183 if (ispresent(g_pars.p_tmsi)) {
1184 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1185 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1186 } else {
1187 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1188 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1189 }
1190 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1191 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1192 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001193 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001194 } else {
1195 SGSN_SIG[sgsn_idx].send(pdu_tx);
1196 }
1197 return pdu_rx;
1198}
1199
1200/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1201 * specified PCU index */
1202private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1203 boolean use_sig := false,integer pcu_idx := 0)
1204runs on BSSGP_ConnHdlr {
1205 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001206 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001207 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1208 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1209 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1210 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1211 timer T := 2.0;
1212 T.start;
1213 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001214 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001215 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001216 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001217 repeat;
1218 }
1219 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1220 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1221 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001222 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001223 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001224 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001225 repeat;
1226 }
Harald Welte158becf2020-12-09 12:32:32 +01001227 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001228 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1229 }
Harald Welte158becf2020-12-09 12:32:32 +01001230 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001231 setverdict(fail, "Paging received on unexpected BVC");
1232 }
1233 [] any from PCU_SIG.receive(exp_rx) {
1234 setverdict(fail, "Paging received on unexpected BVC");
1235 }
Harald Welte158becf2020-12-09 12:32:32 +01001236 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001237 setverdict(fail, "Different Paging than expected received PTP BVC");
1238 }
1239 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1240 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1241 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001242 [not test_done] T.timeout {
1243 setverdict(fail, "Timeout waiting for paging");
1244 }
1245 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001246 }
1247}
1248
Harald Welte7462a592020-11-23 22:07:07 +01001249/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1250private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1251 boolean use_sig := false)
1252runs on BSSGP_ConnHdlr {
1253 var template (present) PDU_BSSGP exp_rx;
1254 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1255 /* Expect paging to propagate to no BSS */
1256 timer T := 2.0;
1257 T.start;
1258 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001259 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001260 setverdict(fail, "Paging received on unexpected BVC");
1261 }
1262 [] any from PCU_SIG.receive(exp_rx) {
1263 setverdict(fail, "Paging received on unexpected BVC");
1264 }
Harald Welte158becf2020-12-09 12:32:32 +01001265 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001266 setverdict(fail, "Different Paging received on PTP BVC");
1267 }
1268 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1269 setverdict(fail, "Different Paging received on SIGNALING BVC");
1270 }
1271 [] T.timeout {
1272 setverdict(pass);
1273 }
1274 }
1275}
1276
Harald Welte0e188242020-11-22 21:46:48 +01001277private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1278{
1279 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1280 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1281 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1282}
1283testcase TC_paging_ps_ptp_bss() runs on test_CT {
1284 var BSSGP_ConnHdlr vc_conn;
1285 f_init();
1286
1287 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1288 vc_conn.done;
1289
1290 f_cleanup();
1291}
1292
1293/* PS-PAGING on PTP-BVC for Location Area */
1294private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1295{
1296 var template (present) PDU_BSSGP exp_rx;
1297 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1298 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1299 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1300}
1301testcase TC_paging_ps_ptp_lac() runs on test_CT {
1302 var BSSGP_ConnHdlr vc_conn;
1303 f_init();
1304
1305 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1306 vc_conn.done;
1307
1308 f_cleanup();
1309}
1310
Harald Welte7462a592020-11-23 22:07:07 +01001311/* PS-PAGING on PTP-BVC for unknown Location Area */
1312private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1313{
1314 var GSM_Types.LocationAreaIdentification unknown_la := {
1315 mcc_mnc := '567F99'H,
1316 lac := 33333
1317 };
1318 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1319 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1320}
1321testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1322 var BSSGP_ConnHdlr vc_conn;
1323 f_init();
1324
1325 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1326 vc_conn.done;
1327
1328 f_cleanup();
1329}
1330
Harald Welte0e188242020-11-22 21:46:48 +01001331/* PS-PAGING on PTP-BVC for Routeing Area */
1332private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1333{
1334 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1335 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1336 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1337}
1338testcase TC_paging_ps_ptp_rac() runs on test_CT {
1339 var BSSGP_ConnHdlr vc_conn;
1340 f_init();
1341
1342 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1343 vc_conn.done;
1344
1345 f_cleanup();
1346}
1347
Harald Welte7462a592020-11-23 22:07:07 +01001348/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1349private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1350{
1351 var RoutingAreaIdentification unknown_ra := {
1352 lai := {
1353 mcc_mnc := '567F99'H,
1354 lac := 33333
1355 },
1356 rac := 254
1357 };
1358 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1359 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1360}
1361testcase TC_paging_ps_ptp_rac_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_ptp_rac_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 PTP-BVC for BVCI (one cell) */
1372private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1373{
1374 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1375 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1376}
1377testcase TC_paging_ps_ptp_bvci() 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_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1382 vc_conn.done;
1383
1384 f_cleanup();
1385}
1386
Harald Welte7462a592020-11-23 22:07:07 +01001387/* PS-PAGING on PTP-BVC for unknown BVCI */
1388private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1389{
1390 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1391 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1392}
1393testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1394 var BSSGP_ConnHdlr vc_conn;
1395 f_init();
1396
1397 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1398 vc_conn.done;
1399
1400 f_cleanup();
1401}
1402
Harald Welte0e188242020-11-22 21:46:48 +01001403/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1404private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1405runs on BSSGP_ConnHdlr {
1406[] PCU_SIG[pcu_idx].receive(exp_rx) {
1407 if (ro_integer_contains(roi, pcu_idx)) {
1408 setverdict(fail, "Received multiple paging on same SIG BVC");
1409 }
1410 roi := roi & { pcu_idx };
1411 repeat;
1412 }
Harald Welte158becf2020-12-09 12:32:32 +01001413[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001414 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1415 }
1416[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1417 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1418 }
Harald Welte158becf2020-12-09 12:32:32 +01001419[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001420 setverdict(fail, "Different Paging than expected received PTP BVC");
1421 }
1422}
1423
1424type record of default ro_default;
1425
1426/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1427private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1428 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1429{
1430 var template (present) PDU_BSSGP exp_rx;
1431 exp_rx := f_send_paging_ps(p4, 0, true);
1432
1433 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1434 var ro_default defaults := {};
1435 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1436 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1437 defaults := defaults & { d };
1438 }
1439 f_sleep(2.0);
1440 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1441 deactivate(defaults[i]);
1442 }
1443 log("Paging received on PCU ", g_roi);
1444
1445 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1446 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1447 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1448 if (exp_on_i and not rx_on_i) {
1449 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1450 }
1451 if (not exp_on_i and rx_on_i) {
1452 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1453 }
1454 }
1455 setverdict(pass);
1456}
1457
1458/* PS-PAGING on SIG-BVC for BSS Area */
1459private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1460{
1461 /* we expect the paging to arrive on all three NSE */
1462 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1463}
1464testcase TC_paging_ps_sig_bss() runs on test_CT {
1465 var BSSGP_ConnHdlr vc_conn;
1466 f_init();
1467
1468 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1469 vc_conn.done;
1470
1471 f_cleanup();
1472}
1473
1474/* PS-PAGING on SIG-BVC for Location Area */
1475private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1476{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001477 /* The first LAC (13135) is shared by all three NSEs */
1478 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1479 /* Reset state */
1480 g_roi := {};
1481 /* Make LAC (13300) available on pcu index 2 */
1482 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1483 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001484}
1485testcase TC_paging_ps_sig_lac() runs on test_CT {
1486 var BSSGP_ConnHdlr vc_conn;
1487 f_init();
1488
1489 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1490 vc_conn.done;
1491
1492 f_cleanup();
1493}
1494
Harald Welte7462a592020-11-23 22:07:07 +01001495/* PS-PAGING on SIG-BVC for unknown Location Area */
1496private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1497{
1498 var GSM_Types.LocationAreaIdentification unknown_la := {
1499 mcc_mnc := '567F99'H,
1500 lac := 33333
1501 };
1502 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1503}
1504testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1505 var BSSGP_ConnHdlr vc_conn;
1506 f_init();
1507
1508 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1509 vc_conn.done;
1510
1511 f_cleanup();
1512}
1513
Harald Welte0e188242020-11-22 21:46:48 +01001514/* PS-PAGING on SIG-BVC for Routeing Area */
1515private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1516{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001517 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001518 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001519 g_roi := {};
1520 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1521 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1522 g_roi := {};
1523 /* PCU index 2 has two matching BVCs with the RA ID */
1524 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1525 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001526}
1527testcase TC_paging_ps_sig_rac() runs on test_CT {
1528 var BSSGP_ConnHdlr vc_conn;
1529 f_init();
1530
1531 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1532 vc_conn.done;
1533
1534 f_cleanup();
1535}
1536
Harald Welte7462a592020-11-23 22:07:07 +01001537/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1538private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1539{
1540 var RoutingAreaIdentification unknown_ra := {
1541 lai := {
1542 mcc_mnc := '567F99'H,
1543 lac := 33333
1544 },
1545 rac := 254
1546 };
1547 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1548}
1549testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1550 var BSSGP_ConnHdlr vc_conn;
1551 f_init();
1552
1553 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1554 vc_conn.done;
1555
1556 f_cleanup();
1557}
1558
Harald Welte0e188242020-11-22 21:46:48 +01001559/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1560private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1561{
1562 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1563}
1564testcase TC_paging_ps_sig_bvci() runs on test_CT {
1565 var BSSGP_ConnHdlr vc_conn;
1566 f_init();
1567
1568 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1569 vc_conn.done;
1570
1571 f_cleanup();
1572}
1573
Harald Welte7462a592020-11-23 22:07:07 +01001574/* PS-PAGING on SIG-BVC for unknown BVCI */
1575private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1576{
1577 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1578}
1579testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1580 var BSSGP_ConnHdlr vc_conn;
1581 f_init();
1582
1583 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1584 vc_conn.done;
1585
1586 f_cleanup();
1587}
1588
1589
Harald Welte0e188242020-11-22 21:46:48 +01001590
1591/***********************************************************************
1592 * PAGING CS procedure
1593 ***********************************************************************/
1594
1595private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1596 boolean use_sig := false)
1597runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1598 var template (value) PDU_BSSGP pdu_tx;
1599 var template (present) PDU_BSSGP pdu_rx;
1600 /* we always specify '0' as BVCI in the templates below, as we override it with
1601 * 'p4' later anyway */
1602 pdu_rx := tr_BSSGP_CS_PAGING(0);
1603 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1604 if (ispresent(g_pars.p_tmsi)) {
1605 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1606 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1607 } else {
1608 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1609 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1610 }
1611 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1612 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1613 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001614 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001615 } else {
1616 SGSN_SIG[sgsn_idx].send(pdu_tx);
1617 }
1618 return pdu_rx;
1619}
1620
1621/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1622 * specified PCU index */
1623private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1624 boolean use_sig := false,integer pcu_idx := 0)
1625runs on BSSGP_ConnHdlr {
1626 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001627 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001628 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1629 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1630 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1631 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1632 timer T := 2.0;
1633 T.start;
1634 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001635 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001636 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001637 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001638 repeat;
1639 }
1640 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1641 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1642 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001643 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001644 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001645 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001646 repeat;
1647 }
Harald Welte158becf2020-12-09 12:32:32 +01001648 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001649 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1650 }
Harald Welte158becf2020-12-09 12:32:32 +01001651 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001652 setverdict(fail, "Paging received on unexpected BVC");
1653 }
1654 [] any from PCU_SIG.receive(exp_rx) {
1655 setverdict(fail, "Paging received on unexpected BVC");
1656 }
Harald Welte158becf2020-12-09 12:32:32 +01001657 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001658 setverdict(fail, "Different Paging than expected received PTP BVC");
1659 }
1660 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1661 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1662 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001663 [not test_done] T.timeout {
1664 setverdict(fail, "Timeout while waiting for paging")
1665 }
1666 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001667 }
1668}
1669
Harald Welte7462a592020-11-23 22:07:07 +01001670/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1671private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1672 boolean use_sig := false)
1673runs on BSSGP_ConnHdlr {
1674 var template (present) PDU_BSSGP exp_rx;
1675 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1676 /* Expect paging to propagate to no BSS */
1677 timer T := 2.0;
1678 T.start;
1679 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001680 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001681 setverdict(fail, "Paging received on unexpected BVC");
1682 }
1683 [] any from PCU_SIG.receive(exp_rx) {
1684 setverdict(fail, "Paging received on unexpected BVC");
1685 }
Harald Welte158becf2020-12-09 12:32:32 +01001686 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001687 setverdict(fail, "Different Paging received on PTP BVC");
1688 }
1689 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1690 setverdict(fail, "Different Paging received on SIGNALING BVC");
1691 }
1692 [] T.timeout {
1693 setverdict(pass);
1694 }
1695 }
1696}
1697
Harald Welte0e188242020-11-22 21:46:48 +01001698private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1699{
1700 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1701 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1702 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1703}
1704testcase TC_paging_cs_ptp_bss() runs on test_CT {
1705 var BSSGP_ConnHdlr vc_conn;
1706 f_init();
1707
1708 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1709 vc_conn.done;
1710
1711 f_cleanup();
1712}
1713
1714/* CS-PAGING on PTP-BVC for Location Area */
1715private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1716{
1717 var template (present) PDU_BSSGP exp_rx;
1718 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1719 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1720 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1721}
1722testcase TC_paging_cs_ptp_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_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1727 vc_conn.done;
1728
1729 f_cleanup();
1730}
1731
Harald Welte7462a592020-11-23 22:07:07 +01001732/* CS-PAGING on PTP-BVC for unknown Location Area */
1733private function f_TC_paging_cs_ptp_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 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1740 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1741}
1742testcase TC_paging_cs_ptp_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_ptp_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 PTP-BVC for Routeing Area */
1753private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1754{
1755 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1756 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1757 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1758}
1759testcase TC_paging_cs_ptp_rac() runs on test_CT {
1760 var BSSGP_ConnHdlr vc_conn;
1761 f_init();
1762
1763 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1764 vc_conn.done;
1765
1766 f_cleanup();
1767}
1768
Harald Welte7462a592020-11-23 22:07:07 +01001769/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1770private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1771{
1772 var RoutingAreaIdentification unknown_ra := {
1773 lai := {
1774 mcc_mnc := '567F99'H,
1775 lac := 33333
1776 },
1777 rac := 254
1778 };
1779 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1780 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1781}
1782testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1783 var BSSGP_ConnHdlr vc_conn;
1784 f_init();
1785
1786 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1787 vc_conn.done;
1788
1789 f_cleanup();
1790}
1791
Harald Welte0e188242020-11-22 21:46:48 +01001792/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1793private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1794{
1795 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1796 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1797}
1798testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1799 var BSSGP_ConnHdlr vc_conn;
1800 f_init();
1801
1802 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1803 vc_conn.done;
1804
1805 f_cleanup();
1806}
1807
Harald Welte7462a592020-11-23 22:07:07 +01001808/* CS-PAGING on PTP-BVC for unknown BVCI */
1809private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1810{
1811 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1812 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1813}
1814testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1815 var BSSGP_ConnHdlr vc_conn;
1816 f_init();
1817
1818 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1819 vc_conn.done;
1820
1821 f_cleanup();
1822}
1823
Harald Welte0e188242020-11-22 21:46:48 +01001824/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1825private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1826 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1827{
1828 var template (present) PDU_BSSGP exp_rx;
1829 exp_rx := f_send_paging_cs(p4, 0, true);
1830
1831 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1832 var ro_default defaults := {};
1833 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1834 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1835 defaults := defaults & { d };
1836 }
1837 f_sleep(2.0);
1838 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1839 deactivate(defaults[i]);
1840 }
1841 log("Paging received on PCU ", g_roi);
1842
1843 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1844 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1845 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1846 if (exp_on_i and not rx_on_i) {
1847 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1848 }
1849 if (not exp_on_i and rx_on_i) {
1850 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1851 }
1852 }
1853 setverdict(pass);
1854}
1855
1856/* CS-PAGING on SIG-BVC for BSS Area */
1857private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1858{
1859 /* we expect the paging to arrive on all three NSE */
1860 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1861}
1862testcase TC_paging_cs_sig_bss() runs on test_CT {
1863 var BSSGP_ConnHdlr vc_conn;
1864 f_init();
1865
1866 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1867 vc_conn.done;
1868
1869 f_cleanup();
1870}
1871
1872/* CS-PAGING on SIG-BVC for Location Area */
1873private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1874{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001875 /* The first LAC (13135) is shared by all three NSEs */
1876 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1877 /* Reset state */
1878 g_roi := {};
1879 /* Make LAC (13300) available on pcu index 2 */
1880 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1881 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001882}
1883testcase TC_paging_cs_sig_lac() runs on test_CT {
1884 var BSSGP_ConnHdlr vc_conn;
1885 f_init();
1886
1887 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1888 vc_conn.done;
1889
1890 f_cleanup();
1891}
1892
Harald Welte7462a592020-11-23 22:07:07 +01001893/* CS-PAGING on SIG-BVC for unknown Location Area */
1894private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1895{
1896 var GSM_Types.LocationAreaIdentification unknown_la := {
1897 mcc_mnc := '567F99'H,
1898 lac := 33333
1899 };
1900 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1901}
1902testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1903 var BSSGP_ConnHdlr vc_conn;
1904 f_init();
1905
1906 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1907 vc_conn.done;
1908
1909 f_cleanup();
1910}
1911
Harald Welte0e188242020-11-22 21:46:48 +01001912/* CS-PAGING on SIG-BVC for Routeing Area */
1913private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1914{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001915 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001916 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001917 g_roi := {};
1918 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1919 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1920 g_roi := {};
1921 /* PCU index 2 has two matching BVCs with the RA ID */
1922 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1923 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
Harald Welte0e188242020-11-22 21:46:48 +01001924}
1925testcase TC_paging_cs_sig_rac() runs on test_CT {
1926 var BSSGP_ConnHdlr vc_conn;
1927 f_init();
1928
1929 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1930 vc_conn.done;
1931
1932 f_cleanup();
1933}
1934
Harald Welte7462a592020-11-23 22:07:07 +01001935/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1936private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1937{
1938 var RoutingAreaIdentification unknown_ra := {
1939 lai := {
1940 mcc_mnc := '567F99'H,
1941 lac := 33333
1942 },
1943 rac := 254
1944 };
1945 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1946}
1947testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1948 var BSSGP_ConnHdlr vc_conn;
1949 f_init();
1950
1951 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1952 vc_conn.done;
1953
1954 f_cleanup();
1955}
1956
Harald Welte0e188242020-11-22 21:46:48 +01001957/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1958private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1959{
1960 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1961}
1962testcase TC_paging_cs_sig_bvci() runs on test_CT {
1963 var BSSGP_ConnHdlr vc_conn;
1964 f_init();
1965
1966 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1967 vc_conn.done;
1968
1969 f_cleanup();
1970}
1971
Harald Welte7462a592020-11-23 22:07:07 +01001972/* CS-PAGING on SIG-BVC for unknown BVCI */
1973private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1974{
1975 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1976}
1977testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1978 var BSSGP_ConnHdlr vc_conn;
1979 f_init();
1980
1981 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1982 vc_conn.done;
1983
1984 f_cleanup();
1985}
1986
Harald Welte4f91c3b2020-12-09 12:25:51 +01001987/***********************************************************************
1988 * FLUSH-LL procedure
1989 ***********************************************************************/
1990
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001991private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1992 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1993 var integer i;
1994 for (i := 0; i < 10; i := i+1) {
1995 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1996 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1997 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1998
1999 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
2000
2001 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2002 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2003 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
2004
2005 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2006 }
2007 setverdict(pass);
2008}
2009testcase TC_flush_ll() runs on test_CT
2010{
2011 var BSSGP_ConnHdlr vc_conn;
2012 f_init();
2013
2014 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
2015 vc_conn.done;
2016 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2017
2018 f_cleanup();
2019}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002020
Harald Welte4f91c3b2020-12-09 12:25:51 +01002021/***********************************************************************
2022 * SGSN-INVOKE-TRACE procedure
2023 ***********************************************************************/
2024
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002025private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2026runs on GlobalTest_CT {
2027[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2028 if (ro_integer_contains(roi, pcu_idx)) {
2029 setverdict(fail, "Received multiple on same SIG BVC");
2030 }
2031 roi := roi & { pcu_idx };
2032 repeat;
2033 }
2034}
2035/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2036testcase TC_trace() runs on GlobalTest_CT
2037{
2038 var BSSGP_ConnHdlr vc_conn;
2039 f_init();
2040 f_global_init();
2041
2042 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2043 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2044
2045 var ro_default defaults := {};
2046 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2047 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2048 }
2049 G_SGSN[0].send(pdu_tx);
2050 f_sleep(2.0);
2051 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2052 deactivate(defaults[i]);
2053 }
2054
2055 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2056 if (not ro_integer_contains(g_roi, i)) {
2057 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2058 }
2059 }
2060 setverdict(pass);
2061
2062 f_cleanup();
2063}
2064
Harald Welte4f91c3b2020-12-09 12:25:51 +01002065/***********************************************************************
2066 * LLC-DISCARDED procedure
2067 ***********************************************************************/
2068
Harald Weltec0351d12020-11-27 22:49:02 +01002069private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2070 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2071
2072 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2073 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2074 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2075
2076 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2077
2078 setverdict(pass);
2079}
2080/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2081testcase TC_llc_discarded() runs on test_CT
2082{
2083 var BSSGP_ConnHdlr vc_conn;
2084 f_init();
2085
2086 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2087 vc_conn.done;
2088 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2089
2090 f_cleanup();
2091}
2092
Harald Welte4f91c3b2020-12-09 12:25:51 +01002093/***********************************************************************
2094 * OVERLOAD procedure
2095 ***********************************************************************/
2096
Harald Weltef20af412020-11-28 16:11:11 +01002097/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2098testcase TC_overload() runs on GlobalTest_CT
2099{
2100 f_init();
2101 f_global_init();
2102
2103 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2104 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2105
2106 var ro_default defaults := {};
2107 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2108 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2109 }
2110 G_SGSN[0].send(pdu_tx);
2111 f_sleep(2.0);
2112 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2113 deactivate(defaults[i]);
2114 }
2115
2116 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2117 if (not ro_integer_contains(g_roi, i)) {
2118 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2119 }
2120 }
2121 setverdict(pass);
2122
2123 f_cleanup();
2124}
2125
Harald Welte4f91c3b2020-12-09 12:25:51 +01002126/***********************************************************************
2127 * BVC-BLOCK / BVC-UNBLOCK procedure
2128 ***********************************************************************/
2129
Harald Welte239aa502020-11-24 23:14:20 +01002130private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2131{
2132 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2133 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2134 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2135
2136 SGSN_MGMT.clear;
2137 PCU_MGMT.clear;
2138
2139 /* block the PTP BVC from the PCU side */
2140 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2141 /* expect state on both PCU and SGSN side to change */
2142 interleave {
2143 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2144 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2145 }
2146 setverdict(pass);
2147}
2148testcase TC_bvc_block_ptp() runs on test_CT
2149{
2150 f_init();
2151 f_sleep(1.0);
2152 f_block_ptp_bvc_from_pcu(0, 0);
2153 f_cleanup();
2154}
2155
2156private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2157{
2158 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2159 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2160 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2161
2162 SGSN_MGMT.clear;
2163 PCU_MGMT.clear;
2164
2165 /* block the PTP BVC from the PCU side */
2166 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2167 /* expect state on both PCU and SGSN side to change */
2168 interleave {
2169 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2170 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2171 }
2172 setverdict(pass);
2173}
2174testcase TC_bvc_unblock_ptp() runs on test_CT
2175{
2176 f_init();
2177 f_sleep(1.0);
2178 f_block_ptp_bvc_from_pcu(0, 0);
2179 f_sleep(1.0);
2180 f_unblock_ptp_bvc_from_pcu(0, 0);
2181 f_cleanup();
2182}
2183
Harald Welte4f91c3b2020-12-09 12:25:51 +01002184/***********************************************************************
2185 * BVC-RESET procedure
2186 ***********************************************************************/
2187
Harald Welte60a8ec72020-11-25 17:12:53 +01002188private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2189[] pt.receive(BssgpStatusIndication:?) { repeat; }
2190}
2191private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2192 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2193 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2194 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2195 }
2196 }
2197 return null;
2198}
2199private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2200{
2201 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2202 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2203 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2204 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2205 var default d;
2206
2207 SGSN_MGMT.clear;
2208 PCU_MGMT.clear;
2209
2210 /* block the PTP BVC from the PCU side */
2211 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2212 /* expect state on both PCU and SGSN side to change */
2213 d := activate(as_ignore_status(SGSN_MGMT));
2214 interleave {
2215 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2216 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2217 }
2218 deactivate(d);
2219 setverdict(pass);
2220}
2221/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2222testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2223{
2224 f_init();
2225 f_sleep(3.0);
2226 f_reset_ptp_bvc_from_pcu(0, 0);
2227 f_cleanup();
2228}
2229
Harald Welte16786e92020-11-27 19:11:56 +01002230private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2231runs on test_CT {
2232 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2233 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2234 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002235 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002236 }
2237}
2238/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2239testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2240
2241 f_init();
2242 f_sleep(3.0);
2243
2244 /* Start BVC-RESET procedure for BVCI=0 */
2245 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2246
2247 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2248 var ro_default defaults := {};
2249 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2250 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2251 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2252 defaults := defaults & { d };
2253 }
2254
2255 timer T := 3.0;
2256 T.start;
2257 alt {
2258 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2259 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2260 }
2261 [] T.timeout;
2262 }
2263
2264 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2265 deactivate(defaults[i]);
2266 }
2267
2268 /* check if BVC-block was received on all expected BVC */
2269 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2270 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2271 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2272 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2273 }
2274 }
2275
2276 /* check if BVC-block was not received on any unexpected BVC is not required as
2277 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002278 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002279 f_cleanup();
2280}
2281
Harald Welte60a8ec72020-11-25 17:12:53 +01002282private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2283{
2284 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2285 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2286 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2287 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2288 var default d;
2289
2290 SGSN_MGMT.clear;
2291 PCU_MGMT.clear;
2292
2293 /* block the PTP BVC from the PCU side */
2294 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2295 /* expect state on both PCU and SGSN side to change */
2296 d := activate(as_ignore_status(PCU_MGMT));
2297 interleave {
2298 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2299 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2300 }
2301 deactivate(d);
2302 setverdict(pass);
2303}
2304/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2305testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2306{
2307 f_init();
2308 f_sleep(3.0);
2309 f_reset_ptp_bvc_from_sgsn(0, 0);
2310 f_cleanup();
2311}
2312
Daniel Willmannef7015f2021-01-08 00:43:56 +01002313private altstep as_ignore_mgmt(BSSGP_BVC_MGMT_PT pt) {
2314 [] pt.receive {repeat; }
2315}
2316
Harald Welte16786e92020-11-27 19:11:56 +01002317private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2318runs on test_CT {
2319 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2320 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2321 roi := roi & { nsei };
Daniel Willmannef7015f2021-01-08 00:43:56 +01002322 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002323 }
2324}
Daniel Willmannef7015f2021-01-08 00:43:56 +01002325
Harald Welte16786e92020-11-27 19:11:56 +01002326/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2327testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2328
2329 f_init();
2330 f_sleep(3.0);
2331
Daniel Willmannef7015f2021-01-08 00:43:56 +01002332 SGSN_MGMT.clear;
2333 PCU_MGMT.clear;
2334
Harald Welte16786e92020-11-27 19:11:56 +01002335 /* Start BVC-RESET procedure for BVCI=0 */
2336 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2337
Daniel Willmannef7015f2021-01-08 00:43:56 +01002338 /* Defaults match in reverse activation order, this one is a catch-all for Status indications
2339 * and reset indications sent from other components (like the ptp_bvcs). If we don't drain
2340 * the port and a different message sits at the front we wait forever and fail the test.
2341 */
2342 var ro_default defaults := { activate(as_ignore_mgmt(PCU_MGMT)) };
2343
Harald Welte16786e92020-11-27 19:11:56 +01002344 /* Activate altsteps: One for each PCU NSE */
Harald Welte16786e92020-11-27 19:11:56 +01002345 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2346 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2347 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2348 defaults := defaults & { d };
2349 }
2350
2351 f_sleep(3.0);
2352
2353 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2354 deactivate(defaults[i]);
2355 }
2356
2357 /* check if BVC-block was received on all expected BVC */
2358 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2359 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2360 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2361 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2362 }
2363 }
2364
2365 /* check if BVC-block was not received on any unexpected BVC is not required as
2366 * such a message would basically run into 'no matching clause' */
2367
2368 f_cleanup();
2369}
2370
Harald Welte299aa482020-12-09 15:10:55 +01002371/***********************************************************************
2372 * FLOW-CONTROL-BVC procedure
2373 ***********************************************************************/
2374
2375private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2376 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2377runs on GlobalTest_CT {
2378 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2379 roi := roi & { sgsn_idx };
2380 if (ispresent(tx_reply)) {
2381 G_SGSN[sgsn_idx].send(tx_reply);
2382 }
2383 }
2384}
2385/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2386testcase TC_fc_bvc() runs on GlobalTest_CT
2387{
2388 f_init();
2389 f_global_init_ptp();
2390
2391 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2392 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2393 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2394 var template (omit) PDU_BSSGP ack_tx :=
2395 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2396
2397 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2398 G_PCU[0].send(pdu_tx);
2399
2400 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2401 var ro_default defaults := {};
2402 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2403 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2404 defaults := defaults & { d };
2405 }
2406
2407 f_sleep(3.0);
2408
2409 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2410 deactivate(defaults[i]);
2411 }
2412
2413 /* check if BVC-block was received on all expected BVC */
2414 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2415 if (not ro_integer_contains(g_roi, i)) {
2416 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2417 }
2418 }
2419
2420 /* Expect ACK on PCU side */
2421 G_PCU[0].receive(ack_tx);
2422
2423 setverdict(pass);
2424
2425 f_cleanup();
2426}
2427
Harald Weltecc3894b2020-12-09 16:50:12 +01002428/***********************************************************************
2429 * FLOW-CONTROL-MS procedure
2430 ***********************************************************************/
2431
2432private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2433 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2434
2435 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2436 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2437 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2438 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2439
2440 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2441 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2442
2443 setverdict(pass);
2444}
2445/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2446testcase TC_fc_ms() runs on test_CT
2447{
2448 var BSSGP_ConnHdlr vc_conn;
2449 f_init();
2450
2451 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2452 vc_conn.done;
2453 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2454
2455 f_cleanup();
2456}
2457
2458
Harald Welte299aa482020-12-09 15:10:55 +01002459
Daniel Willmann423d8f42020-09-08 18:58:22 +02002460control {
2461 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002462 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002463 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002464 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002465 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002466 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002467 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002468 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002469 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002470 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002471 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002472 execute( TC_bvc_block_ptp() );
2473 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002474 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002475 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002476 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002477 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002478 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002479 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2480 execute( TC_load_sharing_dl() );
2481 }
Harald Welte0e188242020-11-22 21:46:48 +01002482
2483 /* PAGING-PS over PTP BVC */
2484 execute( TC_paging_ps_ptp_bss() );
2485 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002486 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002487 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002488 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002489 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002490 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002491
2492 /* PAGING-PS over SIG BVC */
2493 execute( TC_paging_ps_sig_bss() );
2494 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002495 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002496 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002497 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002498 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002499 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002500
2501 /* PAGING-CS over PTP BVC */
2502 execute( TC_paging_cs_ptp_bss() );
2503 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002504 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002505 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002506 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002507 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002508 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002509
2510 /* PAGING-CS over SIG BVC */
2511 execute( TC_paging_cs_sig_bss() );
2512 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002513 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002514 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002515 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002516 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002517 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002518
2519
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002520 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002521 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002522 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002523}
2524
2525
2526}