blob: 9bd05508d2d5987d00f97ba2b24013c8670a6f7e [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 {
507 setverdict(fail, "Timeout waiting for unblock of all BVCs");
508 mtc.stop;
509 }
510 }
511
512 /* iterate over list and check all BVCI */
513 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
514 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
515 if (not ro_integer_contains(bvci_unblocked, bvci)) {
516 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
517 mtc.stop;
518 }
519 }
Harald Welte425d3762020-12-09 14:33:18 +0100520
521 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
522 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200523}
524
525function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100526 var integer i;
527
528 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
529 f_destroy_gb(g_sgsn[i]);
530 }
531 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
532 f_destroy_gb(g_pcu[i]);
533 }
534
535 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200536}
537
538type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
539
540/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100541function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200542 float t_guard := 30.0)
543runs on test_CT return BSSGP_ConnHdlr {
544 var BSSGP_ConnHdlr vc_conn;
545
546 var BSSGP_ConnHdlrPars pars := {
547 imei := f_gen_imei(imsi_suffix),
548 imsi := f_gen_imsi(imsi_suffix),
549 msisdn := f_gen_msisdn(imsi_suffix),
550 p_tmsi := omit,
551 p_tmsi_sig := omit,
552 tlli := f_gprs_tlli_random(),
553 tlli_old := omit,
554 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100555 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100556 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200557 t_guard := t_guard
558 };
559
560 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200561
562 vc_conn.start(f_handler_init(fn, id, pars));
563 return vc_conn;
564}
565
Harald Welte3dd21b32020-11-17 19:21:00 +0100566/* 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 +0100567private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
568runs on BSSGP_ConnHdlr {
569 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100570 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100571 /* unregister + disconnect from old BVC */
572 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100573 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100574 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
575 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
576 }
577 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100578 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100579 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
580 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
581 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
582 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100583 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100584}
585
586/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
587private 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 +0100588 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100589 /* unregister + disconnect from old BVC */
590 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100591 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100592 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
593 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
594 }
595 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100596 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100597 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
598 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
599 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
600 sgsn_ct[port_idx] := bvc_ct;
601}
602
Harald Welte425d3762020-12-09 14:33:18 +0100603private altstep as_gTguard(timer Tguard) {
604 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200605 setverdict(fail, "Tguard timeout");
606 mtc.stop;
607 }
608}
609
610/* first function called in every ConnHdlr */
611private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
612runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100613 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200614 /* do some common stuff like setting up g_pars */
615 g_pars := pars;
616
617 llc := f_llc_create(false);
618
Harald Welte3dd21b32020-11-17 19:21:00 +0100619 /* default connections on PCU side: First BVC of each NSE/PCU */
620 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100621 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100622 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100623
624 /* default connections on SGSN side: First BVC of each NSE/SGSN */
625 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
626 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100627 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200628
629 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100630 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200631
632 /* call the user-supplied test case function */
633 fn.apply(id);
634}
635
Harald Welte1e834f32020-11-15 20:02:59 +0100636private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
637runs on BSSGP_ConnHdlr {
638 PT.call(BSSGP_register_client:{imsi, tlli}) {
639 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
640 }
641}
642
643private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
644runs on BSSGP_ConnHdlr {
645 PT.call(BSSGP_unregister_client:{imsi}) {
646 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
647 }
648}
649
Harald Welte22ef5d92020-11-16 13:35:14 +0100650/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
651friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100652 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100653 var PDU_BSSGP rx;
654 timer T := 1.0;
655
Daniel Willmann4798fd72020-11-24 16:23:29 +0100656 if (use_sig) {
657 PCU_SIG[pcu_idx].send(tx);
658 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100659 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100660 }
661
Harald Welte22ef5d92020-11-16 13:35:14 +0100662 T.start;
663 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100664 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
665 setverdict(pass);
666 }
Harald Welte158becf2020-12-09 12:32:32 +0100667 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100668 setverdict(pass);
669 }
Harald Welte158becf2020-12-09 12:32:32 +0100670 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100671 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
672 mtc.stop;
673 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100674 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
675 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
676 mtc.stop;
677 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100678 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100679 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100680 mtc.stop;
681 }
682 }
683}
684
685/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
686friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100687 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100688 var PDU_BSSGP rx;
689 timer T := 1.0;
690
Daniel Willmann4798fd72020-11-24 16:23:29 +0100691 if (use_sig) {
692 SGSN_SIG[sgsn_idx].send(tx);
693 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100694 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100695 }
696
Harald Welte22ef5d92020-11-16 13:35:14 +0100697 T.start;
698 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100699 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
700 setverdict(pass);
701 }
Harald Welte158becf2020-12-09 12:32:32 +0100702 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100703 setverdict(pass);
704 }
Harald Welte158becf2020-12-09 12:32:32 +0100705 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100706 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
707 mtc.stop;
708 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100709 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
710 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
711 mtc.stop;
712 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100713 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100714 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100715 mtc.stop;
716 }
717 }
718}
Harald Welte1e834f32020-11-15 20:02:59 +0100719
Harald Welte3807ed12020-11-24 19:05:22 +0100720/***********************************************************************
721 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
722 ***********************************************************************/
723
724type component GlobalTest_CT extends test_CT {
725 port BSSGP_PT G_PCU[NUM_PCU];
726 port BSSGP_PT G_SGSN[NUM_SGSN];
727};
728
729private function f_global_init() runs on GlobalTest_CT {
730 var integer i;
731 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
732 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
733 }
734 for (i := 0; i < lengthof(g_pcu); i := i+1) {
735 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
736 }
737}
738
739/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
740friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
741 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
742 var PDU_BSSGP rx;
743 timer T := 1.0;
744
745 G_PCU[pcu_idx].send(tx);
746 T.start;
747 alt {
748 [] G_SGSN[sgsn_idx].receive(exp_rx) {
749 setverdict(pass);
750 }
751 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
752 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
753 mtc.stop;
754 }
755 [] T.timeout {
756 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
757 mtc.stop;
758 }
759 }
760}
761
762/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
763friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
764 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
765 var PDU_BSSGP rx;
766 timer T := 1.0;
767
768 G_SGSN[sgsn_idx].send(tx);
769 T.start;
770 alt {
771 [] G_PCU[pcu_idx].receive(exp_rx) {
772 setverdict(pass);
773 }
774 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
775 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
776 mtc.stop;
777 }
778 [] T.timeout {
779 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
780 mtc.stop;
781 }
782 }
783}
784
785
Daniel Willmann423d8f42020-09-08 18:58:22 +0200786/* TODO:
787 * Detach without Attach
788 * SM procedures without attach / RAU
789 * ATTACH / RAU
790 ** with / without authentication
791 ** with / without P-TMSI allocation
792 * re-transmissions of LLC frames
793 * PDP Context activation
794 ** with different GGSN config in SGSN VTY
795 ** with different PDP context type (v4/v6/v46)
796 ** timeout from GGSN
797 ** multiple / secondary PDP context
798 */
799
800private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
801 f_sleep(5.0);
802 setverdict(pass);
803}
804
805testcase TC_BVC_bringup() runs on test_CT {
806 var BSSGP_ConnHdlr vc_conn;
807 f_init();
808
809 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
810 vc_conn.done;
811
812 f_cleanup();
813}
814
815friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100816 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200817 timer T := 5.0;
818 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100819 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200820 T.start;
821 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100822 [] 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 +0200823 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
824 }
Harald Welte16357a92020-11-17 18:20:00 +0100825 [] 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 +0200826 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
827 mtc.stop;
828 }
829 [] T.timeout {
830 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
831 mtc.stop;
832 }
833 }
834 return '00'O;
835}
836
837friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100838 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200839 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100840 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 +0200841 T.start;
842 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100843 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
844 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200845 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
846 mtc.stop;
847 }
848 [] T.timeout {
849 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
850 mtc.stop;
851 }
852 }
853}
854
855
Harald Welte92686012020-11-15 21:45:49 +0100856/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
857private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100858 var integer ran_idx := 0;
859 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100860 var integer i;
861
Harald Welte0d5fceb2020-11-29 16:04:07 +0100862 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100863 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100864 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 +0100865 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100866 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 +0100867
Harald Welte0d5fceb2020-11-29 16:04:07 +0100868 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100869 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100870 }
871 setverdict(pass);
872}
873
874testcase TC_ul_unitdata() runs on test_CT
875{
876 var BSSGP_ConnHdlr vc_conn;
877 f_init();
878
879 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
880 vc_conn.done;
881 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
882
883 f_cleanup();
884}
885
Harald Welte78d8db92020-11-15 23:27:27 +0100886/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
887private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
888 var integer i;
889
Harald Welte0d5fceb2020-11-29 16:04:07 +0100890 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100891 var octetstring payload := f_rnd_octstring(i);
892 var template (value) PDU_BSSGP pdu_tx :=
893 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
894 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
895 var template (present) PDU_BSSGP pdu_rx :=
896 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
897
Harald Welte0d5fceb2020-11-29 16:04:07 +0100898 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100899 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100900 }
901 setverdict(pass);
902}
903
904testcase TC_dl_unitdata() runs on test_CT
905{
906 var BSSGP_ConnHdlr vc_conn;
907 f_init();
908
909 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
910 vc_conn.done;
911 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
912
913 f_cleanup();
914}
Harald Welte92686012020-11-15 21:45:49 +0100915
Harald Welte6dc2ac42020-11-16 09:16:17 +0100916private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
917 var integer i;
918
919 for (i := 0; i < 10; i := i+1) {
920 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
921 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
922 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
923
Harald Welte22ef5d92020-11-16 13:35:14 +0100924 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100925 }
926 setverdict(pass);
927}
928testcase TC_ra_capability() runs on test_CT
929{
930 var BSSGP_ConnHdlr vc_conn;
931 f_init();
932
933 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
934 vc_conn.done;
935 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
936
937 f_cleanup();
938}
939
Daniel Willmannace3ece2020-11-16 19:53:26 +0100940private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
941 var integer i;
942 var OCT1 tag;
943 for (i := 0; i < 10; i := i+1) {
944 tag := int2oct(23 + i, 1);
945 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
946 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
947 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
948
949 f_pcu2sgsn(pdu_tx, pdu_rx);
950
951 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
952 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
953 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
954
955 f_sgsn2pcu(pdu_tx, pdu_rx);
956 }
957 setverdict(pass);
958}
959testcase TC_ra_capability_upd() runs on test_CT
960{
961 var BSSGP_ConnHdlr vc_conn;
962 f_init();
963
Daniel Willmann54833f22020-11-19 15:43:52 +0100964 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100965 vc_conn.done;
966 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
967
968 f_cleanup();
969}
970
Daniel Willmann165d6612020-11-19 14:27:29 +0100971private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
972 var integer i;
973 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
974 for (i := 0; i < 10; i := i+1) {
975 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
976 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
977 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
978
979 f_pcu2sgsn(pdu_tx, pdu_rx);
980 }
981 setverdict(pass);
982}
983testcase TC_radio_status() runs on test_CT
984{
985 var BSSGP_ConnHdlr vc_conn;
986 f_init();
987
Daniel Willmann54833f22020-11-19 15:43:52 +0100988 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100989 vc_conn.done;
990 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
991
992 f_cleanup();
993}
994
Harald Welte3807ed12020-11-24 19:05:22 +0100995private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100996 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100997
Daniel Willmannfa67f492020-11-19 15:48:05 +0100998 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100999 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001000 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001001 var OCT4 tlli := f_gprs_tlli_random();
1002 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001003 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001004 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001005
Harald Welte3807ed12020-11-24 19:05:22 +01001006 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001007
Harald Welte3807ed12020-11-24 19:05:22 +01001008 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001009 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001010 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001011
Harald Welte3807ed12020-11-24 19:05:22 +01001012 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001013
1014 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001015 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001016 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001017 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001018
Harald Welte3807ed12020-11-24 19:05:22 +01001019 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001020 }
1021 setverdict(pass);
1022}
Harald Welte3807ed12020-11-24 19:05:22 +01001023testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001024{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001025 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001026 f_global_init();
1027 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001028 f_cleanup();
1029}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001030
Harald Welte3807ed12020-11-24 19:05:22 +01001031private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001032 var integer i;
1033
1034 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001035 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001036 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001037 var OCT4 tlli := f_gprs_tlli_random();
1038 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001039 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001040 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001041
Harald Welte3807ed12020-11-24 19:05:22 +01001042 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001043
Harald Welte3807ed12020-11-24 19:05:22 +01001044 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001045 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001046 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001047
Harald Welte3807ed12020-11-24 19:05:22 +01001048 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001049
1050 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001051 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001053 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001054
Harald Welte3807ed12020-11-24 19:05:22 +01001055 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001056 }
1057 setverdict(pass);
1058}
Harald Welte3807ed12020-11-24 19:05:22 +01001059testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001060{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001061 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001062 f_global_init();
1063 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001064 f_cleanup();
1065}
1066
Harald Weltef8ef0282020-11-18 12:16:59 +01001067/* test the load-sharing between multiple NS-VC on the BSS side */
1068private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1069 var integer i;
1070
1071 for (i := 0; i < 10; i := i+1) {
1072 var octetstring payload := f_rnd_octstring(i);
1073 var template (value) PDU_BSSGP pdu_tx :=
1074 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001075 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001076 }
1077 setverdict(pass);
1078}
1079testcase TC_load_sharing_dl() runs on test_CT_NS
1080{
1081 const integer num_ue := 10;
1082 var BSSGP_ConnHdlr vc_conn[num_ue];
1083 f_init();
1084
1085 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1086 * side so we get the raw NsUnitdataIndication and hence observe different
1087 * NSVCI */
1088 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1089 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1090
1091 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1092 * of the NS-VC is ALIVE/UNBLOCKED */
1093 f_sleep(3.0);
1094
1095 /* start parallel components generating DL-UNITDATA from the SGSN side */
1096 for (var integer i:= 0; i < num_ue; i := i+1) {
1097 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1098 }
1099
1100 /* now start counting all the messages that were queued before */
1101 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1102 var ro_integer rx_count := { 0, 0, 0, 0 };
1103 timer T := 2.0;
1104 T.start;
1105 alt {
1106 [] as_NsUdiCount(0, rx_count);
1107 [] as_NsUdiCount(1, rx_count);
1108 [] as_NsUdiCount(2, rx_count);
1109 [] as_NsUdiCount(3, rx_count);
1110 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1111 [] NS.receive(NsStatusIndication:?) { repeat; }
1112 [] NS.receive {
1113 setverdict(fail, "Rx unexpected NS");
1114 mtc.stop;
1115 }
1116 [] T.timeout {
1117 }
1118 }
1119 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1120 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1121 if (rx_count[i] == 0) {
1122 setverdict(fail, "Data not shared over all NSVC");
1123 }
1124 }
1125 setverdict(pass);
1126}
1127private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1128 var NsUnitdataIndication udi;
1129 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1130 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1131 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1132 repeat;
1133 }
1134}
1135type component test_CT_NS extends test_CT {
1136 port NS_PT NS;
1137};
1138
1139
Harald Welte0e188242020-11-22 21:46:48 +01001140/***********************************************************************
1141 * PAGING PS procedure
1142 ***********************************************************************/
1143
1144private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1145 boolean use_sig := false)
1146runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1147 var template (value) PDU_BSSGP pdu_tx;
1148 var template (present) PDU_BSSGP pdu_rx;
1149 /* we always specify '0' as BVCI in the templates below, as we override it with
1150 * 'p4' later anyway */
1151 pdu_rx := tr_BSSGP_PS_PAGING(0);
1152 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1153 if (ispresent(g_pars.p_tmsi)) {
1154 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1155 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1156 } else {
1157 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1158 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1159 }
1160 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1161 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1162 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001163 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001164 } else {
1165 SGSN_SIG[sgsn_idx].send(pdu_tx);
1166 }
1167 return pdu_rx;
1168}
1169
1170/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1171 * specified PCU index */
1172private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1173 boolean use_sig := false,integer pcu_idx := 0)
1174runs on BSSGP_ConnHdlr {
1175 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001176 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001177 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1178 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1179 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1180 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1181 timer T := 2.0;
1182 T.start;
1183 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001184 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001185 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001186 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001187 repeat;
1188 }
1189 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1190 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1191 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001192 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001193 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001194 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001195 repeat;
1196 }
Harald Welte158becf2020-12-09 12:32:32 +01001197 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001198 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1199 }
Harald Welte158becf2020-12-09 12:32:32 +01001200 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001201 setverdict(fail, "Paging received on unexpected BVC");
1202 }
1203 [] any from PCU_SIG.receive(exp_rx) {
1204 setverdict(fail, "Paging received on unexpected BVC");
1205 }
Harald Welte158becf2020-12-09 12:32:32 +01001206 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001207 setverdict(fail, "Different Paging than expected received PTP BVC");
1208 }
1209 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1210 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1211 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001212 [not test_done] T.timeout {
1213 setverdict(fail, "Timeout waiting for paging");
1214 }
1215 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001216 }
1217}
1218
Harald Welte7462a592020-11-23 22:07:07 +01001219/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1220private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1221 boolean use_sig := false)
1222runs on BSSGP_ConnHdlr {
1223 var template (present) PDU_BSSGP exp_rx;
1224 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1225 /* Expect paging to propagate to no BSS */
1226 timer T := 2.0;
1227 T.start;
1228 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001229 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001230 setverdict(fail, "Paging received on unexpected BVC");
1231 }
1232 [] any from PCU_SIG.receive(exp_rx) {
1233 setverdict(fail, "Paging received on unexpected BVC");
1234 }
Harald Welte158becf2020-12-09 12:32:32 +01001235 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001236 setverdict(fail, "Different Paging received on PTP BVC");
1237 }
1238 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1239 setverdict(fail, "Different Paging received on SIGNALING BVC");
1240 }
1241 [] T.timeout {
1242 setverdict(pass);
1243 }
1244 }
1245}
1246
Harald Welte0e188242020-11-22 21:46:48 +01001247private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1248{
1249 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1250 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1251 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1252}
1253testcase TC_paging_ps_ptp_bss() runs on test_CT {
1254 var BSSGP_ConnHdlr vc_conn;
1255 f_init();
1256
1257 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1258 vc_conn.done;
1259
1260 f_cleanup();
1261}
1262
1263/* PS-PAGING on PTP-BVC for Location Area */
1264private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1265{
1266 var template (present) PDU_BSSGP exp_rx;
1267 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1268 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1269 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1270}
1271testcase TC_paging_ps_ptp_lac() runs on test_CT {
1272 var BSSGP_ConnHdlr vc_conn;
1273 f_init();
1274
1275 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1276 vc_conn.done;
1277
1278 f_cleanup();
1279}
1280
Harald Welte7462a592020-11-23 22:07:07 +01001281/* PS-PAGING on PTP-BVC for unknown Location Area */
1282private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1283{
1284 var GSM_Types.LocationAreaIdentification unknown_la := {
1285 mcc_mnc := '567F99'H,
1286 lac := 33333
1287 };
1288 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1289 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1290}
1291testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1292 var BSSGP_ConnHdlr vc_conn;
1293 f_init();
1294
1295 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1296 vc_conn.done;
1297
1298 f_cleanup();
1299}
1300
Harald Welte0e188242020-11-22 21:46:48 +01001301/* PS-PAGING on PTP-BVC for Routeing Area */
1302private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1303{
1304 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1305 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1306 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1307}
1308testcase TC_paging_ps_ptp_rac() runs on test_CT {
1309 var BSSGP_ConnHdlr vc_conn;
1310 f_init();
1311
1312 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1313 vc_conn.done;
1314
1315 f_cleanup();
1316}
1317
Harald Welte7462a592020-11-23 22:07:07 +01001318/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1319private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1320{
1321 var RoutingAreaIdentification unknown_ra := {
1322 lai := {
1323 mcc_mnc := '567F99'H,
1324 lac := 33333
1325 },
1326 rac := 254
1327 };
1328 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1329 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1330}
1331testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1332 var BSSGP_ConnHdlr vc_conn;
1333 f_init();
1334
1335 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1336 vc_conn.done;
1337
1338 f_cleanup();
1339}
1340
Harald Welte0e188242020-11-22 21:46:48 +01001341/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1342private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1343{
1344 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1345 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1346}
1347testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1348 var BSSGP_ConnHdlr vc_conn;
1349 f_init();
1350
1351 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1352 vc_conn.done;
1353
1354 f_cleanup();
1355}
1356
Harald Welte7462a592020-11-23 22:07:07 +01001357/* PS-PAGING on PTP-BVC for unknown BVCI */
1358private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1359{
1360 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1361 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1362}
1363testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1364 var BSSGP_ConnHdlr vc_conn;
1365 f_init();
1366
1367 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1368 vc_conn.done;
1369
1370 f_cleanup();
1371}
1372
Harald Welte0e188242020-11-22 21:46:48 +01001373/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1374private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1375runs on BSSGP_ConnHdlr {
1376[] PCU_SIG[pcu_idx].receive(exp_rx) {
1377 if (ro_integer_contains(roi, pcu_idx)) {
1378 setverdict(fail, "Received multiple paging on same SIG BVC");
1379 }
1380 roi := roi & { pcu_idx };
1381 repeat;
1382 }
Harald Welte158becf2020-12-09 12:32:32 +01001383[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001384 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1385 }
1386[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1387 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1388 }
Harald Welte158becf2020-12-09 12:32:32 +01001389[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001390 setverdict(fail, "Different Paging than expected received PTP BVC");
1391 }
1392}
1393
1394type record of default ro_default;
1395
1396/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1397private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1398 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1399{
1400 var template (present) PDU_BSSGP exp_rx;
1401 exp_rx := f_send_paging_ps(p4, 0, true);
1402
1403 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1404 var ro_default defaults := {};
1405 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1406 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1407 defaults := defaults & { d };
1408 }
1409 f_sleep(2.0);
1410 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1411 deactivate(defaults[i]);
1412 }
1413 log("Paging received on PCU ", g_roi);
1414
1415 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1416 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1417 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1418 if (exp_on_i and not rx_on_i) {
1419 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1420 }
1421 if (not exp_on_i and rx_on_i) {
1422 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1423 }
1424 }
1425 setverdict(pass);
1426}
1427
1428/* PS-PAGING on SIG-BVC for BSS Area */
1429private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1430{
1431 /* we expect the paging to arrive on all three NSE */
1432 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1433}
1434testcase TC_paging_ps_sig_bss() runs on test_CT {
1435 var BSSGP_ConnHdlr vc_conn;
1436 f_init();
1437
1438 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1439 vc_conn.done;
1440
1441 f_cleanup();
1442}
1443
1444/* PS-PAGING on SIG-BVC for Location Area */
1445private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1446{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001447 /* The first LAC (13135) is shared by all three NSEs */
1448 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1449 /* Reset state */
1450 g_roi := {};
1451 /* Make LAC (13300) available on pcu index 2 */
1452 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1453 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 +01001454}
1455testcase TC_paging_ps_sig_lac() runs on test_CT {
1456 var BSSGP_ConnHdlr vc_conn;
1457 f_init();
1458
1459 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1460 vc_conn.done;
1461
1462 f_cleanup();
1463}
1464
Harald Welte7462a592020-11-23 22:07:07 +01001465/* PS-PAGING on SIG-BVC for unknown Location Area */
1466private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1467{
1468 var GSM_Types.LocationAreaIdentification unknown_la := {
1469 mcc_mnc := '567F99'H,
1470 lac := 33333
1471 };
1472 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1473}
1474testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1475 var BSSGP_ConnHdlr vc_conn;
1476 f_init();
1477
1478 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1479 vc_conn.done;
1480
1481 f_cleanup();
1482}
1483
Harald Welte0e188242020-11-22 21:46:48 +01001484/* PS-PAGING on SIG-BVC for Routeing Area */
1485private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1486{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001487 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001488 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 +01001489 g_roi := {};
1490 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1491 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1492 g_roi := {};
1493 /* PCU index 2 has two matching BVCs with the RA ID */
1494 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1495 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 +01001496}
1497testcase TC_paging_ps_sig_rac() runs on test_CT {
1498 var BSSGP_ConnHdlr vc_conn;
1499 f_init();
1500
1501 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1502 vc_conn.done;
1503
1504 f_cleanup();
1505}
1506
Harald Welte7462a592020-11-23 22:07:07 +01001507/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1508private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1509{
1510 var RoutingAreaIdentification unknown_ra := {
1511 lai := {
1512 mcc_mnc := '567F99'H,
1513 lac := 33333
1514 },
1515 rac := 254
1516 };
1517 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1518}
1519testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1520 var BSSGP_ConnHdlr vc_conn;
1521 f_init();
1522
1523 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1524 vc_conn.done;
1525
1526 f_cleanup();
1527}
1528
Harald Welte0e188242020-11-22 21:46:48 +01001529/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1530private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1531{
1532 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1533}
1534testcase TC_paging_ps_sig_bvci() runs on test_CT {
1535 var BSSGP_ConnHdlr vc_conn;
1536 f_init();
1537
1538 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1539 vc_conn.done;
1540
1541 f_cleanup();
1542}
1543
Harald Welte7462a592020-11-23 22:07:07 +01001544/* PS-PAGING on SIG-BVC for unknown BVCI */
1545private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1546{
1547 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1548}
1549testcase TC_paging_ps_sig_bvci_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_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1554 vc_conn.done;
1555
1556 f_cleanup();
1557}
1558
1559
Harald Welte0e188242020-11-22 21:46:48 +01001560
1561/***********************************************************************
1562 * PAGING CS procedure
1563 ***********************************************************************/
1564
1565private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1566 boolean use_sig := false)
1567runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1568 var template (value) PDU_BSSGP pdu_tx;
1569 var template (present) PDU_BSSGP pdu_rx;
1570 /* we always specify '0' as BVCI in the templates below, as we override it with
1571 * 'p4' later anyway */
1572 pdu_rx := tr_BSSGP_CS_PAGING(0);
1573 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1574 if (ispresent(g_pars.p_tmsi)) {
1575 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1576 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1577 } else {
1578 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1579 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1580 }
1581 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1582 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1583 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001584 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001585 } else {
1586 SGSN_SIG[sgsn_idx].send(pdu_tx);
1587 }
1588 return pdu_rx;
1589}
1590
1591/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1592 * specified PCU index */
1593private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1594 boolean use_sig := false,integer pcu_idx := 0)
1595runs on BSSGP_ConnHdlr {
1596 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001597 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001598 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1599 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1600 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1601 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1602 timer T := 2.0;
1603 T.start;
1604 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001605 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001606 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001607 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001608 repeat;
1609 }
1610 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1611 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1612 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001613 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001614 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001615 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001616 repeat;
1617 }
Harald Welte158becf2020-12-09 12:32:32 +01001618 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001619 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1620 }
Harald Welte158becf2020-12-09 12:32:32 +01001621 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001622 setverdict(fail, "Paging received on unexpected BVC");
1623 }
1624 [] any from PCU_SIG.receive(exp_rx) {
1625 setverdict(fail, "Paging received on unexpected BVC");
1626 }
Harald Welte158becf2020-12-09 12:32:32 +01001627 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001628 setverdict(fail, "Different Paging than expected received PTP BVC");
1629 }
1630 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1631 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1632 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001633 [not test_done] T.timeout {
1634 setverdict(fail, "Timeout while waiting for paging")
1635 }
1636 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001637 }
1638}
1639
Harald Welte7462a592020-11-23 22:07:07 +01001640/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1641private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1642 boolean use_sig := false)
1643runs on BSSGP_ConnHdlr {
1644 var template (present) PDU_BSSGP exp_rx;
1645 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1646 /* Expect paging to propagate to no BSS */
1647 timer T := 2.0;
1648 T.start;
1649 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001650 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001651 setverdict(fail, "Paging received on unexpected BVC");
1652 }
1653 [] any from PCU_SIG.receive(exp_rx) {
1654 setverdict(fail, "Paging received on unexpected BVC");
1655 }
Harald Welte158becf2020-12-09 12:32:32 +01001656 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001657 setverdict(fail, "Different Paging received on PTP BVC");
1658 }
1659 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1660 setverdict(fail, "Different Paging received on SIGNALING BVC");
1661 }
1662 [] T.timeout {
1663 setverdict(pass);
1664 }
1665 }
1666}
1667
Harald Welte0e188242020-11-22 21:46:48 +01001668private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1669{
1670 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1671 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1672 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1673}
1674testcase TC_paging_cs_ptp_bss() runs on test_CT {
1675 var BSSGP_ConnHdlr vc_conn;
1676 f_init();
1677
1678 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1679 vc_conn.done;
1680
1681 f_cleanup();
1682}
1683
1684/* CS-PAGING on PTP-BVC for Location Area */
1685private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1686{
1687 var template (present) PDU_BSSGP exp_rx;
1688 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1689 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1690 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1691}
1692testcase TC_paging_cs_ptp_lac() runs on test_CT {
1693 var BSSGP_ConnHdlr vc_conn;
1694 f_init();
1695
1696 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1697 vc_conn.done;
1698
1699 f_cleanup();
1700}
1701
Harald Welte7462a592020-11-23 22:07:07 +01001702/* CS-PAGING on PTP-BVC for unknown Location Area */
1703private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1704{
1705 var GSM_Types.LocationAreaIdentification unknown_la := {
1706 mcc_mnc := '567F99'H,
1707 lac := 33333
1708 };
1709 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1710 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1711}
1712testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1713 var BSSGP_ConnHdlr vc_conn;
1714 f_init();
1715
1716 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1717 vc_conn.done;
1718
1719 f_cleanup();
1720}
1721
Harald Welte0e188242020-11-22 21:46:48 +01001722/* CS-PAGING on PTP-BVC for Routeing Area */
1723private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1724{
1725 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1726 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1727 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1728}
1729testcase TC_paging_cs_ptp_rac() runs on test_CT {
1730 var BSSGP_ConnHdlr vc_conn;
1731 f_init();
1732
1733 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1734 vc_conn.done;
1735
1736 f_cleanup();
1737}
1738
Harald Welte7462a592020-11-23 22:07:07 +01001739/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1740private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1741{
1742 var RoutingAreaIdentification unknown_ra := {
1743 lai := {
1744 mcc_mnc := '567F99'H,
1745 lac := 33333
1746 },
1747 rac := 254
1748 };
1749 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1750 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1751}
1752testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1753 var BSSGP_ConnHdlr vc_conn;
1754 f_init();
1755
1756 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1757 vc_conn.done;
1758
1759 f_cleanup();
1760}
1761
Harald Welte0e188242020-11-22 21:46:48 +01001762/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1763private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1764{
1765 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1766 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1767}
1768testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1769 var BSSGP_ConnHdlr vc_conn;
1770 f_init();
1771
1772 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1773 vc_conn.done;
1774
1775 f_cleanup();
1776}
1777
Harald Welte7462a592020-11-23 22:07:07 +01001778/* CS-PAGING on PTP-BVC for unknown BVCI */
1779private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1780{
1781 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1782 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1783}
1784testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1785 var BSSGP_ConnHdlr vc_conn;
1786 f_init();
1787
1788 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1789 vc_conn.done;
1790
1791 f_cleanup();
1792}
1793
Harald Welte0e188242020-11-22 21:46:48 +01001794/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1795private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1796 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1797{
1798 var template (present) PDU_BSSGP exp_rx;
1799 exp_rx := f_send_paging_cs(p4, 0, true);
1800
1801 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1802 var ro_default defaults := {};
1803 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1804 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1805 defaults := defaults & { d };
1806 }
1807 f_sleep(2.0);
1808 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1809 deactivate(defaults[i]);
1810 }
1811 log("Paging received on PCU ", g_roi);
1812
1813 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1814 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1815 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1816 if (exp_on_i and not rx_on_i) {
1817 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1818 }
1819 if (not exp_on_i and rx_on_i) {
1820 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1821 }
1822 }
1823 setverdict(pass);
1824}
1825
1826/* CS-PAGING on SIG-BVC for BSS Area */
1827private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1828{
1829 /* we expect the paging to arrive on all three NSE */
1830 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1831}
1832testcase TC_paging_cs_sig_bss() runs on test_CT {
1833 var BSSGP_ConnHdlr vc_conn;
1834 f_init();
1835
1836 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1837 vc_conn.done;
1838
1839 f_cleanup();
1840}
1841
1842/* CS-PAGING on SIG-BVC for Location Area */
1843private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1844{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001845 /* The first LAC (13135) is shared by all three NSEs */
1846 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1847 /* Reset state */
1848 g_roi := {};
1849 /* Make LAC (13300) available on pcu index 2 */
1850 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1851 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 +01001852}
1853testcase TC_paging_cs_sig_lac() runs on test_CT {
1854 var BSSGP_ConnHdlr vc_conn;
1855 f_init();
1856
1857 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1858 vc_conn.done;
1859
1860 f_cleanup();
1861}
1862
Harald Welte7462a592020-11-23 22:07:07 +01001863/* CS-PAGING on SIG-BVC for unknown Location Area */
1864private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1865{
1866 var GSM_Types.LocationAreaIdentification unknown_la := {
1867 mcc_mnc := '567F99'H,
1868 lac := 33333
1869 };
1870 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1871}
1872testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1873 var BSSGP_ConnHdlr vc_conn;
1874 f_init();
1875
1876 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1877 vc_conn.done;
1878
1879 f_cleanup();
1880}
1881
Harald Welte0e188242020-11-22 21:46:48 +01001882/* CS-PAGING on SIG-BVC for Routeing Area */
1883private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1884{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001885 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001886 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 +01001887 g_roi := {};
1888 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1889 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1890 g_roi := {};
1891 /* PCU index 2 has two matching BVCs with the RA ID */
1892 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1893 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 +01001894}
1895testcase TC_paging_cs_sig_rac() runs on test_CT {
1896 var BSSGP_ConnHdlr vc_conn;
1897 f_init();
1898
1899 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1900 vc_conn.done;
1901
1902 f_cleanup();
1903}
1904
Harald Welte7462a592020-11-23 22:07:07 +01001905/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1906private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1907{
1908 var RoutingAreaIdentification unknown_ra := {
1909 lai := {
1910 mcc_mnc := '567F99'H,
1911 lac := 33333
1912 },
1913 rac := 254
1914 };
1915 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1916}
1917testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1918 var BSSGP_ConnHdlr vc_conn;
1919 f_init();
1920
1921 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1922 vc_conn.done;
1923
1924 f_cleanup();
1925}
1926
Harald Welte0e188242020-11-22 21:46:48 +01001927/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1928private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1929{
1930 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1931}
1932testcase TC_paging_cs_sig_bvci() runs on test_CT {
1933 var BSSGP_ConnHdlr vc_conn;
1934 f_init();
1935
1936 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1937 vc_conn.done;
1938
1939 f_cleanup();
1940}
1941
Harald Welte7462a592020-11-23 22:07:07 +01001942/* CS-PAGING on SIG-BVC for unknown BVCI */
1943private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1944{
1945 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1946}
1947testcase TC_paging_cs_sig_bvci_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_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1952 vc_conn.done;
1953
1954 f_cleanup();
1955}
1956
Harald Welte4f91c3b2020-12-09 12:25:51 +01001957/***********************************************************************
1958 * FLUSH-LL procedure
1959 ***********************************************************************/
1960
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001961private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1962 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1963 var integer i;
1964 for (i := 0; i < 10; i := i+1) {
1965 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1966 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1967 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1968
1969 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1970
1971 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1972 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1973 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1974
1975 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1976 }
1977 setverdict(pass);
1978}
1979testcase TC_flush_ll() runs on test_CT
1980{
1981 var BSSGP_ConnHdlr vc_conn;
1982 f_init();
1983
1984 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1985 vc_conn.done;
1986 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1987
1988 f_cleanup();
1989}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001990
Harald Welte4f91c3b2020-12-09 12:25:51 +01001991/***********************************************************************
1992 * SGSN-INVOKE-TRACE procedure
1993 ***********************************************************************/
1994
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001995private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1996runs on GlobalTest_CT {
1997[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1998 if (ro_integer_contains(roi, pcu_idx)) {
1999 setverdict(fail, "Received multiple on same SIG BVC");
2000 }
2001 roi := roi & { pcu_idx };
2002 repeat;
2003 }
2004}
2005/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2006testcase TC_trace() runs on GlobalTest_CT
2007{
2008 var BSSGP_ConnHdlr vc_conn;
2009 f_init();
2010 f_global_init();
2011
2012 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2013 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2014
2015 var ro_default defaults := {};
2016 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2017 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2018 }
2019 G_SGSN[0].send(pdu_tx);
2020 f_sleep(2.0);
2021 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2022 deactivate(defaults[i]);
2023 }
2024
2025 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2026 if (not ro_integer_contains(g_roi, i)) {
2027 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2028 }
2029 }
2030 setverdict(pass);
2031
2032 f_cleanup();
2033}
2034
Harald Welte4f91c3b2020-12-09 12:25:51 +01002035/***********************************************************************
2036 * LLC-DISCARDED procedure
2037 ***********************************************************************/
2038
Harald Weltec0351d12020-11-27 22:49:02 +01002039private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2040 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2041
2042 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2043 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2044 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2045
2046 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2047
2048 setverdict(pass);
2049}
2050/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2051testcase TC_llc_discarded() runs on test_CT
2052{
2053 var BSSGP_ConnHdlr vc_conn;
2054 f_init();
2055
2056 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2057 vc_conn.done;
2058 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2059
2060 f_cleanup();
2061}
2062
Harald Welte4f91c3b2020-12-09 12:25:51 +01002063/***********************************************************************
2064 * OVERLOAD procedure
2065 ***********************************************************************/
2066
Harald Weltef20af412020-11-28 16:11:11 +01002067/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2068testcase TC_overload() runs on GlobalTest_CT
2069{
2070 f_init();
2071 f_global_init();
2072
2073 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2074 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2075
2076 var ro_default defaults := {};
2077 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2078 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2079 }
2080 G_SGSN[0].send(pdu_tx);
2081 f_sleep(2.0);
2082 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2083 deactivate(defaults[i]);
2084 }
2085
2086 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2087 if (not ro_integer_contains(g_roi, i)) {
2088 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2089 }
2090 }
2091 setverdict(pass);
2092
2093 f_cleanup();
2094}
2095
Harald Welte4f91c3b2020-12-09 12:25:51 +01002096/***********************************************************************
2097 * BVC-BLOCK / BVC-UNBLOCK procedure
2098 ***********************************************************************/
2099
Harald Welte239aa502020-11-24 23:14:20 +01002100private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2101{
2102 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2103 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2104 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2105
2106 SGSN_MGMT.clear;
2107 PCU_MGMT.clear;
2108
2109 /* block the PTP BVC from the PCU side */
2110 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2111 /* expect state on both PCU and SGSN side to change */
2112 interleave {
2113 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2114 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2115 }
2116 setverdict(pass);
2117}
2118testcase TC_bvc_block_ptp() runs on test_CT
2119{
2120 f_init();
2121 f_sleep(1.0);
2122 f_block_ptp_bvc_from_pcu(0, 0);
2123 f_cleanup();
2124}
2125
2126private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2127{
2128 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2129 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2130 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2131
2132 SGSN_MGMT.clear;
2133 PCU_MGMT.clear;
2134
2135 /* block the PTP BVC from the PCU side */
2136 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2137 /* expect state on both PCU and SGSN side to change */
2138 interleave {
2139 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2140 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2141 }
2142 setverdict(pass);
2143}
2144testcase TC_bvc_unblock_ptp() runs on test_CT
2145{
2146 f_init();
2147 f_sleep(1.0);
2148 f_block_ptp_bvc_from_pcu(0, 0);
2149 f_sleep(1.0);
2150 f_unblock_ptp_bvc_from_pcu(0, 0);
2151 f_cleanup();
2152}
2153
Harald Welte4f91c3b2020-12-09 12:25:51 +01002154/***********************************************************************
2155 * BVC-RESET procedure
2156 ***********************************************************************/
2157
Harald Welte60a8ec72020-11-25 17:12:53 +01002158private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2159[] pt.receive(BssgpStatusIndication:?) { repeat; }
2160}
2161private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2162 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2163 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2164 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2165 }
2166 }
2167 return null;
2168}
2169private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2170{
2171 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2172 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2173 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2174 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2175 var default d;
2176
2177 SGSN_MGMT.clear;
2178 PCU_MGMT.clear;
2179
2180 /* block the PTP BVC from the PCU side */
2181 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2182 /* expect state on both PCU and SGSN side to change */
2183 d := activate(as_ignore_status(SGSN_MGMT));
2184 interleave {
2185 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2186 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2187 }
2188 deactivate(d);
2189 setverdict(pass);
2190}
2191/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2192testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2193{
2194 f_init();
2195 f_sleep(3.0);
2196 f_reset_ptp_bvc_from_pcu(0, 0);
2197 f_cleanup();
2198}
2199
Harald Welte16786e92020-11-27 19:11:56 +01002200private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2201runs on test_CT {
2202 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2203 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2204 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002205 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002206 }
2207}
2208/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2209testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2210
2211 f_init();
2212 f_sleep(3.0);
2213
2214 /* Start BVC-RESET procedure for BVCI=0 */
2215 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2216
2217 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2218 var ro_default defaults := {};
2219 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2220 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2221 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2222 defaults := defaults & { d };
2223 }
2224
2225 timer T := 3.0;
2226 T.start;
2227 alt {
2228 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2229 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2230 }
2231 [] T.timeout;
2232 }
2233
2234 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2235 deactivate(defaults[i]);
2236 }
2237
2238 /* check if BVC-block was received on all expected BVC */
2239 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2240 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2241 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2242 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2243 }
2244 }
2245
2246 /* check if BVC-block was not received on any unexpected BVC is not required as
2247 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002248 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002249 f_cleanup();
2250}
2251
Harald Welte60a8ec72020-11-25 17:12:53 +01002252private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2253{
2254 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2255 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2256 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2257 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2258 var default d;
2259
2260 SGSN_MGMT.clear;
2261 PCU_MGMT.clear;
2262
2263 /* block the PTP BVC from the PCU side */
2264 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2265 /* expect state on both PCU and SGSN side to change */
2266 d := activate(as_ignore_status(PCU_MGMT));
2267 interleave {
2268 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2269 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2270 }
2271 deactivate(d);
2272 setverdict(pass);
2273}
2274/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2275testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2276{
2277 f_init();
2278 f_sleep(3.0);
2279 f_reset_ptp_bvc_from_sgsn(0, 0);
2280 f_cleanup();
2281}
2282
Harald Welte16786e92020-11-27 19:11:56 +01002283private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2284runs on test_CT {
2285 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2286 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2287 roi := roi & { nsei };
2288 }
2289}
2290/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2291testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2292
2293 f_init();
2294 f_sleep(3.0);
2295
2296 /* Start BVC-RESET procedure for BVCI=0 */
2297 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2298
2299 /* Activate altsteps: One for each PCU NSE */
2300 var ro_default defaults := {};
2301 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2302 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2303 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2304 defaults := defaults & { d };
2305 }
2306
2307 f_sleep(3.0);
2308
2309 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2310 deactivate(defaults[i]);
2311 }
2312
2313 /* check if BVC-block was received on all expected BVC */
2314 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2315 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2316 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2317 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2318 }
2319 }
2320
2321 /* check if BVC-block was not received on any unexpected BVC is not required as
2322 * such a message would basically run into 'no matching clause' */
2323
2324 f_cleanup();
2325}
2326
Daniel Willmann423d8f42020-09-08 18:58:22 +02002327control {
2328 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002329 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002330 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002331 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002332 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002333 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002334 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002335 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002336 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002337 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002338 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002339 execute( TC_bvc_block_ptp() );
2340 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002341 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002342 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002343 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002344 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002345 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002346 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2347 execute( TC_load_sharing_dl() );
2348 }
Harald Welte0e188242020-11-22 21:46:48 +01002349
2350 /* PAGING-PS over PTP BVC */
2351 execute( TC_paging_ps_ptp_bss() );
2352 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002353 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002354 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002355 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002356 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002357 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002358
2359 /* PAGING-PS over SIG BVC */
2360 execute( TC_paging_ps_sig_bss() );
2361 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002362 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002363 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002364 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002365 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002366 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002367
2368 /* PAGING-CS over PTP BVC */
2369 execute( TC_paging_cs_ptp_bss() );
2370 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002371 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002372 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002373 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002374 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002375 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002376
2377 /* PAGING-CS over SIG BVC */
2378 execute( TC_paging_cs_sig_bss() );
2379 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002380 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002381 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002382 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002383 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002384 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002385
2386
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002387 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002388}
2389
2390
2391}