blob: 2077e0fc1d275157729656f05cc0059776c2d5f0 [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
Harald Welte299aa482020-12-09 15:10:55 +0100729/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100730private function f_global_init() runs on GlobalTest_CT {
731 var integer i;
732 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
733 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
734 }
735 for (i := 0; i < lengthof(g_pcu); i := i+1) {
736 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
737 }
738}
739
Harald Welte299aa482020-12-09 15:10:55 +0100740/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
741private function f_global_init_ptp() runs on GlobalTest_CT {
742 var integer i;
743 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
744 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
745 }
746 for (i := 0; i < lengthof(g_pcu); i := i+1) {
747 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
748 }
749}
750
Harald Welte3807ed12020-11-24 19:05:22 +0100751/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
752friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
753 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
754 var PDU_BSSGP rx;
755 timer T := 1.0;
756
757 G_PCU[pcu_idx].send(tx);
758 T.start;
759 alt {
760 [] G_SGSN[sgsn_idx].receive(exp_rx) {
761 setverdict(pass);
762 }
763 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
764 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
765 mtc.stop;
766 }
767 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100768 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100769 mtc.stop;
770 }
771 }
772}
773
774/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
775friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
776 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
777 var PDU_BSSGP rx;
778 timer T := 1.0;
779
780 G_SGSN[sgsn_idx].send(tx);
781 T.start;
782 alt {
783 [] G_PCU[pcu_idx].receive(exp_rx) {
784 setverdict(pass);
785 }
786 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
787 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
788 mtc.stop;
789 }
790 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100791 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100792 mtc.stop;
793 }
794 }
795}
796
797
Daniel Willmann423d8f42020-09-08 18:58:22 +0200798/* TODO:
799 * Detach without Attach
800 * SM procedures without attach / RAU
801 * ATTACH / RAU
802 ** with / without authentication
803 ** with / without P-TMSI allocation
804 * re-transmissions of LLC frames
805 * PDP Context activation
806 ** with different GGSN config in SGSN VTY
807 ** with different PDP context type (v4/v6/v46)
808 ** timeout from GGSN
809 ** multiple / secondary PDP context
810 */
811
812private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
813 f_sleep(5.0);
814 setverdict(pass);
815}
816
817testcase TC_BVC_bringup() runs on test_CT {
818 var BSSGP_ConnHdlr vc_conn;
819 f_init();
820
821 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
822 vc_conn.done;
823
824 f_cleanup();
825}
826
827friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100828 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200829 timer T := 5.0;
830 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100831 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200832 T.start;
833 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100834 [] 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 +0200835 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
836 }
Harald Welte16357a92020-11-17 18:20:00 +0100837 [] 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 +0200838 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
839 mtc.stop;
840 }
841 [] T.timeout {
842 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
843 mtc.stop;
844 }
845 }
846 return '00'O;
847}
848
849friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100850 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200851 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100852 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 +0200853 T.start;
854 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100855 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
856 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200857 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
858 mtc.stop;
859 }
860 [] T.timeout {
861 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
862 mtc.stop;
863 }
864 }
865}
866
867
Harald Welte92686012020-11-15 21:45:49 +0100868/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
869private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100870 var integer ran_idx := 0;
871 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100872 var integer i;
873
Harald Welte0d5fceb2020-11-29 16:04:07 +0100874 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100875 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100876 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 +0100877 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100878 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 +0100879
Harald Welte0d5fceb2020-11-29 16:04:07 +0100880 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100881 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100882 }
883 setverdict(pass);
884}
885
886testcase TC_ul_unitdata() runs on test_CT
887{
888 var BSSGP_ConnHdlr vc_conn;
889 f_init();
890
891 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
892 vc_conn.done;
893 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
894
895 f_cleanup();
896}
897
Harald Welte78d8db92020-11-15 23:27:27 +0100898/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
899private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
900 var integer i;
901
Harald Welte0d5fceb2020-11-29 16:04:07 +0100902 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100903 var octetstring payload := f_rnd_octstring(i);
904 var template (value) PDU_BSSGP pdu_tx :=
905 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
906 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
907 var template (present) PDU_BSSGP pdu_rx :=
908 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
909
Harald Welte0d5fceb2020-11-29 16:04:07 +0100910 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100911 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100912 }
913 setverdict(pass);
914}
915
916testcase TC_dl_unitdata() runs on test_CT
917{
918 var BSSGP_ConnHdlr vc_conn;
919 f_init();
920
921 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
922 vc_conn.done;
923 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
924
925 f_cleanup();
926}
Harald Welte92686012020-11-15 21:45:49 +0100927
Harald Welte6dc2ac42020-11-16 09:16:17 +0100928private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
929 var integer i;
930
931 for (i := 0; i < 10; i := i+1) {
932 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
933 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
934 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
935
Harald Welte22ef5d92020-11-16 13:35:14 +0100936 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100937 }
938 setverdict(pass);
939}
940testcase TC_ra_capability() runs on test_CT
941{
942 var BSSGP_ConnHdlr vc_conn;
943 f_init();
944
945 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
946 vc_conn.done;
947 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
948
949 f_cleanup();
950}
951
Daniel Willmannace3ece2020-11-16 19:53:26 +0100952private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
953 var integer i;
954 var OCT1 tag;
955 for (i := 0; i < 10; i := i+1) {
956 tag := int2oct(23 + i, 1);
957 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
958 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
959 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
960
961 f_pcu2sgsn(pdu_tx, pdu_rx);
962
963 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
964 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
965 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
966
967 f_sgsn2pcu(pdu_tx, pdu_rx);
968 }
969 setverdict(pass);
970}
971testcase TC_ra_capability_upd() runs on test_CT
972{
973 var BSSGP_ConnHdlr vc_conn;
974 f_init();
975
Daniel Willmann54833f22020-11-19 15:43:52 +0100976 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100977 vc_conn.done;
978 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
979
980 f_cleanup();
981}
982
Daniel Willmann165d6612020-11-19 14:27:29 +0100983private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
984 var integer i;
985 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
986 for (i := 0; i < 10; i := i+1) {
987 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
988 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
989 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
990
991 f_pcu2sgsn(pdu_tx, pdu_rx);
992 }
993 setverdict(pass);
994}
995testcase TC_radio_status() runs on test_CT
996{
997 var BSSGP_ConnHdlr vc_conn;
998 f_init();
999
Daniel Willmann54833f22020-11-19 15:43:52 +01001000 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001001 vc_conn.done;
1002 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1003
1004 f_cleanup();
1005}
1006
Harald Welte3807ed12020-11-24 19:05:22 +01001007private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001008 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001009
Daniel Willmannfa67f492020-11-19 15:48:05 +01001010 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001011 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001012 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001013 var OCT4 tlli := f_gprs_tlli_random();
1014 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001015 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001016 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001017
Harald Welte3807ed12020-11-24 19:05:22 +01001018 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001019
Harald Welte3807ed12020-11-24 19:05:22 +01001020 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001021 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001022 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001023
Harald Welte3807ed12020-11-24 19:05:22 +01001024 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001025
1026 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001027 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001028 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001029 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001030
Harald Welte3807ed12020-11-24 19:05:22 +01001031 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001032 }
1033 setverdict(pass);
1034}
Harald Welte3807ed12020-11-24 19:05:22 +01001035testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001036{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001037 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001038 f_global_init();
1039 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001040 f_cleanup();
1041}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001042
Harald Welte3807ed12020-11-24 19:05:22 +01001043private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001044 var integer i;
1045
1046 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001047 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001048 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001049 var OCT4 tlli := f_gprs_tlli_random();
1050 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001051 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001052 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001053
Harald Welte3807ed12020-11-24 19:05:22 +01001054 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001055
Harald Welte3807ed12020-11-24 19:05:22 +01001056 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001057 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001058 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001059
Harald Welte3807ed12020-11-24 19:05:22 +01001060 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001061
1062 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001063 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001064 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001065 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001066
Harald Welte3807ed12020-11-24 19:05:22 +01001067 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001068 }
1069 setverdict(pass);
1070}
Harald Welte3807ed12020-11-24 19:05:22 +01001071testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001072{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001073 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001074 f_global_init();
1075 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001076 f_cleanup();
1077}
1078
Harald Weltef8ef0282020-11-18 12:16:59 +01001079/* test the load-sharing between multiple NS-VC on the BSS side */
1080private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1081 var integer i;
1082
1083 for (i := 0; i < 10; i := i+1) {
1084 var octetstring payload := f_rnd_octstring(i);
1085 var template (value) PDU_BSSGP pdu_tx :=
1086 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001087 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001088 }
1089 setverdict(pass);
1090}
1091testcase TC_load_sharing_dl() runs on test_CT_NS
1092{
1093 const integer num_ue := 10;
1094 var BSSGP_ConnHdlr vc_conn[num_ue];
1095 f_init();
1096
1097 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1098 * side so we get the raw NsUnitdataIndication and hence observe different
1099 * NSVCI */
1100 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1101 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1102
1103 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1104 * of the NS-VC is ALIVE/UNBLOCKED */
1105 f_sleep(3.0);
1106
1107 /* start parallel components generating DL-UNITDATA from the SGSN side */
1108 for (var integer i:= 0; i < num_ue; i := i+1) {
1109 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1110 }
1111
1112 /* now start counting all the messages that were queued before */
1113 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1114 var ro_integer rx_count := { 0, 0, 0, 0 };
1115 timer T := 2.0;
1116 T.start;
1117 alt {
1118 [] as_NsUdiCount(0, rx_count);
1119 [] as_NsUdiCount(1, rx_count);
1120 [] as_NsUdiCount(2, rx_count);
1121 [] as_NsUdiCount(3, rx_count);
1122 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1123 [] NS.receive(NsStatusIndication:?) { repeat; }
1124 [] NS.receive {
1125 setverdict(fail, "Rx unexpected NS");
1126 mtc.stop;
1127 }
1128 [] T.timeout {
1129 }
1130 }
1131 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1132 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1133 if (rx_count[i] == 0) {
1134 setverdict(fail, "Data not shared over all NSVC");
1135 }
1136 }
1137 setverdict(pass);
1138}
1139private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1140 var NsUnitdataIndication udi;
1141 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1142 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1143 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1144 repeat;
1145 }
1146}
1147type component test_CT_NS extends test_CT {
1148 port NS_PT NS;
1149};
1150
1151
Harald Welte0e188242020-11-22 21:46:48 +01001152/***********************************************************************
1153 * PAGING PS procedure
1154 ***********************************************************************/
1155
1156private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1157 boolean use_sig := false)
1158runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1159 var template (value) PDU_BSSGP pdu_tx;
1160 var template (present) PDU_BSSGP pdu_rx;
1161 /* we always specify '0' as BVCI in the templates below, as we override it with
1162 * 'p4' later anyway */
1163 pdu_rx := tr_BSSGP_PS_PAGING(0);
1164 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1165 if (ispresent(g_pars.p_tmsi)) {
1166 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1167 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1168 } else {
1169 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1170 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1171 }
1172 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1173 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1174 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001175 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001176 } else {
1177 SGSN_SIG[sgsn_idx].send(pdu_tx);
1178 }
1179 return pdu_rx;
1180}
1181
1182/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1183 * specified PCU index */
1184private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1185 boolean use_sig := false,integer pcu_idx := 0)
1186runs on BSSGP_ConnHdlr {
1187 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001188 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001189 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1190 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1191 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1192 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1193 timer T := 2.0;
1194 T.start;
1195 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001196 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001197 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001198 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001199 repeat;
1200 }
1201 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1202 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1203 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001204 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001205 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001206 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001207 repeat;
1208 }
Harald Welte158becf2020-12-09 12:32:32 +01001209 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001210 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1211 }
Harald Welte158becf2020-12-09 12:32:32 +01001212 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001213 setverdict(fail, "Paging received on unexpected BVC");
1214 }
1215 [] any from PCU_SIG.receive(exp_rx) {
1216 setverdict(fail, "Paging received on unexpected BVC");
1217 }
Harald Welte158becf2020-12-09 12:32:32 +01001218 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001219 setverdict(fail, "Different Paging than expected received PTP BVC");
1220 }
1221 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1222 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1223 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001224 [not test_done] T.timeout {
1225 setverdict(fail, "Timeout waiting for paging");
1226 }
1227 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001228 }
1229}
1230
Harald Welte7462a592020-11-23 22:07:07 +01001231/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1232private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1233 boolean use_sig := false)
1234runs on BSSGP_ConnHdlr {
1235 var template (present) PDU_BSSGP exp_rx;
1236 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1237 /* Expect paging to propagate to no BSS */
1238 timer T := 2.0;
1239 T.start;
1240 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001241 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001242 setverdict(fail, "Paging received on unexpected BVC");
1243 }
1244 [] any from PCU_SIG.receive(exp_rx) {
1245 setverdict(fail, "Paging received on unexpected BVC");
1246 }
Harald Welte158becf2020-12-09 12:32:32 +01001247 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001248 setverdict(fail, "Different Paging received on PTP BVC");
1249 }
1250 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1251 setverdict(fail, "Different Paging received on SIGNALING BVC");
1252 }
1253 [] T.timeout {
1254 setverdict(pass);
1255 }
1256 }
1257}
1258
Harald Welte0e188242020-11-22 21:46:48 +01001259private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1260{
1261 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1262 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1263 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1264}
1265testcase TC_paging_ps_ptp_bss() runs on test_CT {
1266 var BSSGP_ConnHdlr vc_conn;
1267 f_init();
1268
1269 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1270 vc_conn.done;
1271
1272 f_cleanup();
1273}
1274
1275/* PS-PAGING on PTP-BVC for Location Area */
1276private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1277{
1278 var template (present) PDU_BSSGP exp_rx;
1279 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1280 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1281 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1282}
1283testcase TC_paging_ps_ptp_lac() runs on test_CT {
1284 var BSSGP_ConnHdlr vc_conn;
1285 f_init();
1286
1287 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1288 vc_conn.done;
1289
1290 f_cleanup();
1291}
1292
Harald Welte7462a592020-11-23 22:07:07 +01001293/* PS-PAGING on PTP-BVC for unknown Location Area */
1294private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1295{
1296 var GSM_Types.LocationAreaIdentification unknown_la := {
1297 mcc_mnc := '567F99'H,
1298 lac := 33333
1299 };
1300 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1301 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1302}
1303testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1304 var BSSGP_ConnHdlr vc_conn;
1305 f_init();
1306
1307 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1308 vc_conn.done;
1309
1310 f_cleanup();
1311}
1312
Harald Welte0e188242020-11-22 21:46:48 +01001313/* PS-PAGING on PTP-BVC for Routeing Area */
1314private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1315{
1316 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1317 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1318 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1319}
1320testcase TC_paging_ps_ptp_rac() runs on test_CT {
1321 var BSSGP_ConnHdlr vc_conn;
1322 f_init();
1323
1324 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1325 vc_conn.done;
1326
1327 f_cleanup();
1328}
1329
Harald Welte7462a592020-11-23 22:07:07 +01001330/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1331private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1332{
1333 var RoutingAreaIdentification unknown_ra := {
1334 lai := {
1335 mcc_mnc := '567F99'H,
1336 lac := 33333
1337 },
1338 rac := 254
1339 };
1340 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1341 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1342}
1343testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1344 var BSSGP_ConnHdlr vc_conn;
1345 f_init();
1346
1347 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1348 vc_conn.done;
1349
1350 f_cleanup();
1351}
1352
Harald Welte0e188242020-11-22 21:46:48 +01001353/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1354private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1355{
1356 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1357 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1358}
1359testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1360 var BSSGP_ConnHdlr vc_conn;
1361 f_init();
1362
1363 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1364 vc_conn.done;
1365
1366 f_cleanup();
1367}
1368
Harald Welte7462a592020-11-23 22:07:07 +01001369/* PS-PAGING on PTP-BVC for unknown BVCI */
1370private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1371{
1372 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1373 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1374}
1375testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1376 var BSSGP_ConnHdlr vc_conn;
1377 f_init();
1378
1379 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1380 vc_conn.done;
1381
1382 f_cleanup();
1383}
1384
Harald Welte0e188242020-11-22 21:46:48 +01001385/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1386private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1387runs on BSSGP_ConnHdlr {
1388[] PCU_SIG[pcu_idx].receive(exp_rx) {
1389 if (ro_integer_contains(roi, pcu_idx)) {
1390 setverdict(fail, "Received multiple paging on same SIG BVC");
1391 }
1392 roi := roi & { pcu_idx };
1393 repeat;
1394 }
Harald Welte158becf2020-12-09 12:32:32 +01001395[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001396 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1397 }
1398[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1399 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1400 }
Harald Welte158becf2020-12-09 12:32:32 +01001401[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001402 setverdict(fail, "Different Paging than expected received PTP BVC");
1403 }
1404}
1405
1406type record of default ro_default;
1407
1408/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1409private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1410 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1411{
1412 var template (present) PDU_BSSGP exp_rx;
1413 exp_rx := f_send_paging_ps(p4, 0, true);
1414
1415 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1416 var ro_default defaults := {};
1417 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1418 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1419 defaults := defaults & { d };
1420 }
1421 f_sleep(2.0);
1422 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1423 deactivate(defaults[i]);
1424 }
1425 log("Paging received on PCU ", g_roi);
1426
1427 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1428 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1429 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1430 if (exp_on_i and not rx_on_i) {
1431 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1432 }
1433 if (not exp_on_i and rx_on_i) {
1434 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1435 }
1436 }
1437 setverdict(pass);
1438}
1439
1440/* PS-PAGING on SIG-BVC for BSS Area */
1441private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1442{
1443 /* we expect the paging to arrive on all three NSE */
1444 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1445}
1446testcase TC_paging_ps_sig_bss() runs on test_CT {
1447 var BSSGP_ConnHdlr vc_conn;
1448 f_init();
1449
1450 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1451 vc_conn.done;
1452
1453 f_cleanup();
1454}
1455
1456/* PS-PAGING on SIG-BVC for Location Area */
1457private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1458{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001459 /* The first LAC (13135) is shared by all three NSEs */
1460 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1461 /* Reset state */
1462 g_roi := {};
1463 /* Make LAC (13300) available on pcu index 2 */
1464 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1465 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 +01001466}
1467testcase TC_paging_ps_sig_lac() runs on test_CT {
1468 var BSSGP_ConnHdlr vc_conn;
1469 f_init();
1470
1471 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1472 vc_conn.done;
1473
1474 f_cleanup();
1475}
1476
Harald Welte7462a592020-11-23 22:07:07 +01001477/* PS-PAGING on SIG-BVC for unknown Location Area */
1478private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1479{
1480 var GSM_Types.LocationAreaIdentification unknown_la := {
1481 mcc_mnc := '567F99'H,
1482 lac := 33333
1483 };
1484 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1485}
1486testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1487 var BSSGP_ConnHdlr vc_conn;
1488 f_init();
1489
1490 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1491 vc_conn.done;
1492
1493 f_cleanup();
1494}
1495
Harald Welte0e188242020-11-22 21:46:48 +01001496/* PS-PAGING on SIG-BVC for Routeing Area */
1497private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1498{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001499 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001500 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 +01001501 g_roi := {};
1502 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1503 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1504 g_roi := {};
1505 /* PCU index 2 has two matching BVCs with the RA ID */
1506 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1507 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 +01001508}
1509testcase TC_paging_ps_sig_rac() runs on test_CT {
1510 var BSSGP_ConnHdlr vc_conn;
1511 f_init();
1512
1513 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1514 vc_conn.done;
1515
1516 f_cleanup();
1517}
1518
Harald Welte7462a592020-11-23 22:07:07 +01001519/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1520private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1521{
1522 var RoutingAreaIdentification unknown_ra := {
1523 lai := {
1524 mcc_mnc := '567F99'H,
1525 lac := 33333
1526 },
1527 rac := 254
1528 };
1529 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1530}
1531testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
1534
1535 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1536 vc_conn.done;
1537
1538 f_cleanup();
1539}
1540
Harald Welte0e188242020-11-22 21:46:48 +01001541/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1542private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1543{
1544 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1545}
1546testcase TC_paging_ps_sig_bvci() runs on test_CT {
1547 var BSSGP_ConnHdlr vc_conn;
1548 f_init();
1549
1550 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1551 vc_conn.done;
1552
1553 f_cleanup();
1554}
1555
Harald Welte7462a592020-11-23 22:07:07 +01001556/* PS-PAGING on SIG-BVC for unknown BVCI */
1557private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1558{
1559 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1560}
1561testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1562 var BSSGP_ConnHdlr vc_conn;
1563 f_init();
1564
1565 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1566 vc_conn.done;
1567
1568 f_cleanup();
1569}
1570
1571
Harald Welte0e188242020-11-22 21:46:48 +01001572
1573/***********************************************************************
1574 * PAGING CS procedure
1575 ***********************************************************************/
1576
1577private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1578 boolean use_sig := false)
1579runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1580 var template (value) PDU_BSSGP pdu_tx;
1581 var template (present) PDU_BSSGP pdu_rx;
1582 /* we always specify '0' as BVCI in the templates below, as we override it with
1583 * 'p4' later anyway */
1584 pdu_rx := tr_BSSGP_CS_PAGING(0);
1585 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1586 if (ispresent(g_pars.p_tmsi)) {
1587 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1588 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1589 } else {
1590 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1591 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1592 }
1593 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1594 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1595 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001596 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001597 } else {
1598 SGSN_SIG[sgsn_idx].send(pdu_tx);
1599 }
1600 return pdu_rx;
1601}
1602
1603/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1604 * specified PCU index */
1605private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1606 boolean use_sig := false,integer pcu_idx := 0)
1607runs on BSSGP_ConnHdlr {
1608 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001609 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001610 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1611 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1612 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1613 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1614 timer T := 2.0;
1615 T.start;
1616 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001617 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001618 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001619 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001620 repeat;
1621 }
1622 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1623 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1624 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001625 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001626 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001627 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001628 repeat;
1629 }
Harald Welte158becf2020-12-09 12:32:32 +01001630 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001631 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1632 }
Harald Welte158becf2020-12-09 12:32:32 +01001633 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001634 setverdict(fail, "Paging received on unexpected BVC");
1635 }
1636 [] any from PCU_SIG.receive(exp_rx) {
1637 setverdict(fail, "Paging received on unexpected BVC");
1638 }
Harald Welte158becf2020-12-09 12:32:32 +01001639 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001640 setverdict(fail, "Different Paging than expected received PTP BVC");
1641 }
1642 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1643 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1644 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001645 [not test_done] T.timeout {
1646 setverdict(fail, "Timeout while waiting for paging")
1647 }
1648 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001649 }
1650}
1651
Harald Welte7462a592020-11-23 22:07:07 +01001652/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1653private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1654 boolean use_sig := false)
1655runs on BSSGP_ConnHdlr {
1656 var template (present) PDU_BSSGP exp_rx;
1657 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1658 /* Expect paging to propagate to no BSS */
1659 timer T := 2.0;
1660 T.start;
1661 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001662 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001663 setverdict(fail, "Paging received on unexpected BVC");
1664 }
1665 [] any from PCU_SIG.receive(exp_rx) {
1666 setverdict(fail, "Paging received on unexpected BVC");
1667 }
Harald Welte158becf2020-12-09 12:32:32 +01001668 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001669 setverdict(fail, "Different Paging received on PTP BVC");
1670 }
1671 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1672 setverdict(fail, "Different Paging received on SIGNALING BVC");
1673 }
1674 [] T.timeout {
1675 setverdict(pass);
1676 }
1677 }
1678}
1679
Harald Welte0e188242020-11-22 21:46:48 +01001680private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1681{
1682 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1683 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1684 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1685}
1686testcase TC_paging_cs_ptp_bss() runs on test_CT {
1687 var BSSGP_ConnHdlr vc_conn;
1688 f_init();
1689
1690 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1691 vc_conn.done;
1692
1693 f_cleanup();
1694}
1695
1696/* CS-PAGING on PTP-BVC for Location Area */
1697private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1698{
1699 var template (present) PDU_BSSGP exp_rx;
1700 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1701 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1702 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1703}
1704testcase TC_paging_cs_ptp_lac() runs on test_CT {
1705 var BSSGP_ConnHdlr vc_conn;
1706 f_init();
1707
1708 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1709 vc_conn.done;
1710
1711 f_cleanup();
1712}
1713
Harald Welte7462a592020-11-23 22:07:07 +01001714/* CS-PAGING on PTP-BVC for unknown Location Area */
1715private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1716{
1717 var GSM_Types.LocationAreaIdentification unknown_la := {
1718 mcc_mnc := '567F99'H,
1719 lac := 33333
1720 };
1721 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1722 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1723}
1724testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1725 var BSSGP_ConnHdlr vc_conn;
1726 f_init();
1727
1728 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1729 vc_conn.done;
1730
1731 f_cleanup();
1732}
1733
Harald Welte0e188242020-11-22 21:46:48 +01001734/* CS-PAGING on PTP-BVC for Routeing Area */
1735private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1736{
1737 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1738 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1739 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1740}
1741testcase TC_paging_cs_ptp_rac() runs on test_CT {
1742 var BSSGP_ConnHdlr vc_conn;
1743 f_init();
1744
1745 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1746 vc_conn.done;
1747
1748 f_cleanup();
1749}
1750
Harald Welte7462a592020-11-23 22:07:07 +01001751/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1752private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1753{
1754 var RoutingAreaIdentification unknown_ra := {
1755 lai := {
1756 mcc_mnc := '567F99'H,
1757 lac := 33333
1758 },
1759 rac := 254
1760 };
1761 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1762 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1763}
1764testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1765 var BSSGP_ConnHdlr vc_conn;
1766 f_init();
1767
1768 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1769 vc_conn.done;
1770
1771 f_cleanup();
1772}
1773
Harald Welte0e188242020-11-22 21:46:48 +01001774/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1775private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1776{
1777 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1778 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1779}
1780testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1781 var BSSGP_ConnHdlr vc_conn;
1782 f_init();
1783
1784 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1785 vc_conn.done;
1786
1787 f_cleanup();
1788}
1789
Harald Welte7462a592020-11-23 22:07:07 +01001790/* CS-PAGING on PTP-BVC for unknown BVCI */
1791private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1792{
1793 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1794 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1795}
1796testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1797 var BSSGP_ConnHdlr vc_conn;
1798 f_init();
1799
1800 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1801 vc_conn.done;
1802
1803 f_cleanup();
1804}
1805
Harald Welte0e188242020-11-22 21:46:48 +01001806/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1807private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1808 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1809{
1810 var template (present) PDU_BSSGP exp_rx;
1811 exp_rx := f_send_paging_cs(p4, 0, true);
1812
1813 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1814 var ro_default defaults := {};
1815 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1816 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1817 defaults := defaults & { d };
1818 }
1819 f_sleep(2.0);
1820 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1821 deactivate(defaults[i]);
1822 }
1823 log("Paging received on PCU ", g_roi);
1824
1825 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1826 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1827 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1828 if (exp_on_i and not rx_on_i) {
1829 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1830 }
1831 if (not exp_on_i and rx_on_i) {
1832 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1833 }
1834 }
1835 setverdict(pass);
1836}
1837
1838/* CS-PAGING on SIG-BVC for BSS Area */
1839private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1840{
1841 /* we expect the paging to arrive on all three NSE */
1842 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1843}
1844testcase TC_paging_cs_sig_bss() runs on test_CT {
1845 var BSSGP_ConnHdlr vc_conn;
1846 f_init();
1847
1848 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1849 vc_conn.done;
1850
1851 f_cleanup();
1852}
1853
1854/* CS-PAGING on SIG-BVC for Location Area */
1855private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1856{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001857 /* The first LAC (13135) is shared by all three NSEs */
1858 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1859 /* Reset state */
1860 g_roi := {};
1861 /* Make LAC (13300) available on pcu index 2 */
1862 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1863 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 +01001864}
1865testcase TC_paging_cs_sig_lac() runs on test_CT {
1866 var BSSGP_ConnHdlr vc_conn;
1867 f_init();
1868
1869 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1870 vc_conn.done;
1871
1872 f_cleanup();
1873}
1874
Harald Welte7462a592020-11-23 22:07:07 +01001875/* CS-PAGING on SIG-BVC for unknown Location Area */
1876private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1877{
1878 var GSM_Types.LocationAreaIdentification unknown_la := {
1879 mcc_mnc := '567F99'H,
1880 lac := 33333
1881 };
1882 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1883}
1884testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1885 var BSSGP_ConnHdlr vc_conn;
1886 f_init();
1887
1888 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1889 vc_conn.done;
1890
1891 f_cleanup();
1892}
1893
Harald Welte0e188242020-11-22 21:46:48 +01001894/* CS-PAGING on SIG-BVC for Routeing Area */
1895private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1896{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001897 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001898 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 +01001899 g_roi := {};
1900 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1901 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1902 g_roi := {};
1903 /* PCU index 2 has two matching BVCs with the RA ID */
1904 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1905 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 +01001906}
1907testcase TC_paging_cs_sig_rac() runs on test_CT {
1908 var BSSGP_ConnHdlr vc_conn;
1909 f_init();
1910
1911 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1912 vc_conn.done;
1913
1914 f_cleanup();
1915}
1916
Harald Welte7462a592020-11-23 22:07:07 +01001917/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1918private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1919{
1920 var RoutingAreaIdentification unknown_ra := {
1921 lai := {
1922 mcc_mnc := '567F99'H,
1923 lac := 33333
1924 },
1925 rac := 254
1926 };
1927 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1928}
1929testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1930 var BSSGP_ConnHdlr vc_conn;
1931 f_init();
1932
1933 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1934 vc_conn.done;
1935
1936 f_cleanup();
1937}
1938
Harald Welte0e188242020-11-22 21:46:48 +01001939/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1940private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1941{
1942 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1943}
1944testcase TC_paging_cs_sig_bvci() runs on test_CT {
1945 var BSSGP_ConnHdlr vc_conn;
1946 f_init();
1947
1948 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1949 vc_conn.done;
1950
1951 f_cleanup();
1952}
1953
Harald Welte7462a592020-11-23 22:07:07 +01001954/* CS-PAGING on SIG-BVC for unknown BVCI */
1955private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1956{
1957 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1958}
1959testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1960 var BSSGP_ConnHdlr vc_conn;
1961 f_init();
1962
1963 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1964 vc_conn.done;
1965
1966 f_cleanup();
1967}
1968
Harald Welte4f91c3b2020-12-09 12:25:51 +01001969/***********************************************************************
1970 * FLUSH-LL procedure
1971 ***********************************************************************/
1972
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001973private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1974 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1975 var integer i;
1976 for (i := 0; i < 10; i := i+1) {
1977 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1978 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1979 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1980
1981 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1982
1983 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1984 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1985 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1986
1987 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1988 }
1989 setverdict(pass);
1990}
1991testcase TC_flush_ll() runs on test_CT
1992{
1993 var BSSGP_ConnHdlr vc_conn;
1994 f_init();
1995
1996 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1997 vc_conn.done;
1998 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1999
2000 f_cleanup();
2001}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002002
Harald Welte4f91c3b2020-12-09 12:25:51 +01002003/***********************************************************************
2004 * SGSN-INVOKE-TRACE procedure
2005 ***********************************************************************/
2006
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002007private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2008runs on GlobalTest_CT {
2009[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2010 if (ro_integer_contains(roi, pcu_idx)) {
2011 setverdict(fail, "Received multiple on same SIG BVC");
2012 }
2013 roi := roi & { pcu_idx };
2014 repeat;
2015 }
2016}
2017/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2018testcase TC_trace() runs on GlobalTest_CT
2019{
2020 var BSSGP_ConnHdlr vc_conn;
2021 f_init();
2022 f_global_init();
2023
2024 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2025 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2026
2027 var ro_default defaults := {};
2028 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2029 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2030 }
2031 G_SGSN[0].send(pdu_tx);
2032 f_sleep(2.0);
2033 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2034 deactivate(defaults[i]);
2035 }
2036
2037 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2038 if (not ro_integer_contains(g_roi, i)) {
2039 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2040 }
2041 }
2042 setverdict(pass);
2043
2044 f_cleanup();
2045}
2046
Harald Welte4f91c3b2020-12-09 12:25:51 +01002047/***********************************************************************
2048 * LLC-DISCARDED procedure
2049 ***********************************************************************/
2050
Harald Weltec0351d12020-11-27 22:49:02 +01002051private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2052 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2053
2054 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2055 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2056 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2057
2058 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2059
2060 setverdict(pass);
2061}
2062/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2063testcase TC_llc_discarded() runs on test_CT
2064{
2065 var BSSGP_ConnHdlr vc_conn;
2066 f_init();
2067
2068 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2069 vc_conn.done;
2070 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2071
2072 f_cleanup();
2073}
2074
Harald Welte4f91c3b2020-12-09 12:25:51 +01002075/***********************************************************************
2076 * OVERLOAD procedure
2077 ***********************************************************************/
2078
Harald Weltef20af412020-11-28 16:11:11 +01002079/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2080testcase TC_overload() runs on GlobalTest_CT
2081{
2082 f_init();
2083 f_global_init();
2084
2085 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2086 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2087
2088 var ro_default defaults := {};
2089 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2090 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2091 }
2092 G_SGSN[0].send(pdu_tx);
2093 f_sleep(2.0);
2094 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2095 deactivate(defaults[i]);
2096 }
2097
2098 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2099 if (not ro_integer_contains(g_roi, i)) {
2100 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2101 }
2102 }
2103 setverdict(pass);
2104
2105 f_cleanup();
2106}
2107
Harald Welte4f91c3b2020-12-09 12:25:51 +01002108/***********************************************************************
2109 * BVC-BLOCK / BVC-UNBLOCK procedure
2110 ***********************************************************************/
2111
Harald Welte239aa502020-11-24 23:14:20 +01002112private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2113{
2114 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2115 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2116 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2117
2118 SGSN_MGMT.clear;
2119 PCU_MGMT.clear;
2120
2121 /* block the PTP BVC from the PCU side */
2122 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2123 /* expect state on both PCU and SGSN side to change */
2124 interleave {
2125 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2126 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2127 }
2128 setverdict(pass);
2129}
2130testcase TC_bvc_block_ptp() runs on test_CT
2131{
2132 f_init();
2133 f_sleep(1.0);
2134 f_block_ptp_bvc_from_pcu(0, 0);
2135 f_cleanup();
2136}
2137
2138private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2139{
2140 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2141 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2142 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2143
2144 SGSN_MGMT.clear;
2145 PCU_MGMT.clear;
2146
2147 /* block the PTP BVC from the PCU side */
2148 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2149 /* expect state on both PCU and SGSN side to change */
2150 interleave {
2151 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2152 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2153 }
2154 setverdict(pass);
2155}
2156testcase TC_bvc_unblock_ptp() runs on test_CT
2157{
2158 f_init();
2159 f_sleep(1.0);
2160 f_block_ptp_bvc_from_pcu(0, 0);
2161 f_sleep(1.0);
2162 f_unblock_ptp_bvc_from_pcu(0, 0);
2163 f_cleanup();
2164}
2165
Harald Welte4f91c3b2020-12-09 12:25:51 +01002166/***********************************************************************
2167 * BVC-RESET procedure
2168 ***********************************************************************/
2169
Harald Welte60a8ec72020-11-25 17:12:53 +01002170private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2171[] pt.receive(BssgpStatusIndication:?) { repeat; }
2172}
2173private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2174 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2175 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2176 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2177 }
2178 }
2179 return null;
2180}
2181private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2182{
2183 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2184 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2185 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2186 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2187 var default d;
2188
2189 SGSN_MGMT.clear;
2190 PCU_MGMT.clear;
2191
2192 /* block the PTP BVC from the PCU side */
2193 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2194 /* expect state on both PCU and SGSN side to change */
2195 d := activate(as_ignore_status(SGSN_MGMT));
2196 interleave {
2197 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2198 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2199 }
2200 deactivate(d);
2201 setverdict(pass);
2202}
2203/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2204testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2205{
2206 f_init();
2207 f_sleep(3.0);
2208 f_reset_ptp_bvc_from_pcu(0, 0);
2209 f_cleanup();
2210}
2211
Harald Welte16786e92020-11-27 19:11:56 +01002212private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2213runs on test_CT {
2214 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2215 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2216 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002217 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002218 }
2219}
2220/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2221testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2222
2223 f_init();
2224 f_sleep(3.0);
2225
2226 /* Start BVC-RESET procedure for BVCI=0 */
2227 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2228
2229 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2230 var ro_default defaults := {};
2231 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2232 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2233 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2234 defaults := defaults & { d };
2235 }
2236
2237 timer T := 3.0;
2238 T.start;
2239 alt {
2240 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2241 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2242 }
2243 [] T.timeout;
2244 }
2245
2246 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2247 deactivate(defaults[i]);
2248 }
2249
2250 /* check if BVC-block was received on all expected BVC */
2251 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2252 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2253 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2254 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2255 }
2256 }
2257
2258 /* check if BVC-block was not received on any unexpected BVC is not required as
2259 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002260 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002261 f_cleanup();
2262}
2263
Harald Welte60a8ec72020-11-25 17:12:53 +01002264private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2265{
2266 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2267 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2268 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2269 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2270 var default d;
2271
2272 SGSN_MGMT.clear;
2273 PCU_MGMT.clear;
2274
2275 /* block the PTP BVC from the PCU side */
2276 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2277 /* expect state on both PCU and SGSN side to change */
2278 d := activate(as_ignore_status(PCU_MGMT));
2279 interleave {
2280 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2281 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2282 }
2283 deactivate(d);
2284 setverdict(pass);
2285}
2286/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2287testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2288{
2289 f_init();
2290 f_sleep(3.0);
2291 f_reset_ptp_bvc_from_sgsn(0, 0);
2292 f_cleanup();
2293}
2294
Harald Welte16786e92020-11-27 19:11:56 +01002295private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2296runs on test_CT {
2297 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2298 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2299 roi := roi & { nsei };
2300 }
2301}
2302/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2303testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2304
2305 f_init();
2306 f_sleep(3.0);
2307
2308 /* Start BVC-RESET procedure for BVCI=0 */
2309 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2310
2311 /* Activate altsteps: One for each PCU NSE */
2312 var ro_default defaults := {};
2313 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2314 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2315 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2316 defaults := defaults & { d };
2317 }
2318
2319 f_sleep(3.0);
2320
2321 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2322 deactivate(defaults[i]);
2323 }
2324
2325 /* check if BVC-block was received on all expected BVC */
2326 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2327 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2328 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2329 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2330 }
2331 }
2332
2333 /* check if BVC-block was not received on any unexpected BVC is not required as
2334 * such a message would basically run into 'no matching clause' */
2335
2336 f_cleanup();
2337}
2338
Harald Welte299aa482020-12-09 15:10:55 +01002339/***********************************************************************
2340 * FLOW-CONTROL-BVC procedure
2341 ***********************************************************************/
2342
2343private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2344 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2345runs on GlobalTest_CT {
2346 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2347 roi := roi & { sgsn_idx };
2348 if (ispresent(tx_reply)) {
2349 G_SGSN[sgsn_idx].send(tx_reply);
2350 }
2351 }
2352}
2353/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2354testcase TC_fc_bvc() runs on GlobalTest_CT
2355{
2356 f_init();
2357 f_global_init_ptp();
2358
2359 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2360 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2361 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2362 var template (omit) PDU_BSSGP ack_tx :=
2363 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2364
2365 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2366 G_PCU[0].send(pdu_tx);
2367
2368 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2369 var ro_default defaults := {};
2370 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2371 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2372 defaults := defaults & { d };
2373 }
2374
2375 f_sleep(3.0);
2376
2377 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2378 deactivate(defaults[i]);
2379 }
2380
2381 /* check if BVC-block was received on all expected BVC */
2382 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2383 if (not ro_integer_contains(g_roi, i)) {
2384 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2385 }
2386 }
2387
2388 /* Expect ACK on PCU side */
2389 G_PCU[0].receive(ack_tx);
2390
2391 setverdict(pass);
2392
2393 f_cleanup();
2394}
2395
Harald Weltecc3894b2020-12-09 16:50:12 +01002396/***********************************************************************
2397 * FLOW-CONTROL-MS procedure
2398 ***********************************************************************/
2399
2400private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2401 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2402
2403 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2404 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2405 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2406 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2407
2408 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2409 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2410
2411 setverdict(pass);
2412}
2413/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2414testcase TC_fc_ms() runs on test_CT
2415{
2416 var BSSGP_ConnHdlr vc_conn;
2417 f_init();
2418
2419 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2420 vc_conn.done;
2421 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2422
2423 f_cleanup();
2424}
2425
2426
Harald Welte299aa482020-12-09 15:10:55 +01002427
Daniel Willmann423d8f42020-09-08 18:58:22 +02002428control {
2429 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002430 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002431 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002432 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002433 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002434 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002435 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002436 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002437 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002438 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002439 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002440 execute( TC_bvc_block_ptp() );
2441 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002442 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002443 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002444 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002445 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002446 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002447 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2448 execute( TC_load_sharing_dl() );
2449 }
Harald Welte0e188242020-11-22 21:46:48 +01002450
2451 /* PAGING-PS over PTP BVC */
2452 execute( TC_paging_ps_ptp_bss() );
2453 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002454 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002455 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002456 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002457 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002458 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002459
2460 /* PAGING-PS over SIG BVC */
2461 execute( TC_paging_ps_sig_bss() );
2462 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002463 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002464 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002465 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002466 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002467 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002468
2469 /* PAGING-CS over PTP BVC */
2470 execute( TC_paging_cs_ptp_bss() );
2471 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002472 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002473 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002474 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002475 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002476 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002477
2478 /* PAGING-CS over SIG BVC */
2479 execute( TC_paging_cs_sig_bss() );
2480 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002481 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002482 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002483 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002484 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002485 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002486
2487
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002488 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002489 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002490 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002491}
2492
2493
2494}