blob: 59154e8c2ce3e74fffc0faac9d0a3a2a2248d3a7 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
Harald Welteb9f0fdc2020-12-09 14:44:50 +010017import from Misc_Helpers all;
Daniel Willmann423d8f42020-09-08 18:58:22 +020018import from GSM_Types all;
19import from Native_Functions all;
20import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
24import from SCCPasp_Types all;
25import from Osmocom_Gb_Types all;
26
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from TELNETasp_PortType all;
34import from Osmocom_VTY_Functions all;
35
36import from LLC_Types all;
37import from LLC_Templates all;
38
39import from GSM_RR_Types all;
40
Harald Welte6d63f742020-11-15 19:44:04 +010041/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
42const BcdMccMnc c_mcc_mnc := '262F42'H;
43
Harald Welte0d5fceb2020-11-29 16:04:07 +010044/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
45const integer max_fr_info_size := 1600;
46
Daniel Willmann423d8f42020-09-08 18:58:22 +020047modulepar {
Harald Weltef6e59b02020-12-08 08:29:09 +010048 boolean mp_enable_bss_load_sharing := false;
Daniel Willmann2c9300f2020-12-01 10:54:08 +010049 /* SGSN NS configuration */
Harald Welte6d63f742020-11-15 19:44:04 +010050 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020051 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020052 nsei := 101,
53 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010054 handle_sns := false,
55 nsvc := {
56 {
57 provider := {
58 ip := {
59 address_family := AF_INET,
60 local_udp_port := 7777,
61 local_ip := "127.0.0.1",
62 remote_udp_port := 23000,
63 remote_ip := "127.0.0.1"
64 }
65 },
66 nsvci := 101
67 }
68 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020069 }
70 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +010071 /* BSS NSEI start at 2000 + x
72 * NSVCI start from value of NSEI + 100
73 * UDP port is NSVCI * 10 */
Harald Welte6d63f742020-11-15 19:44:04 +010074 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020075 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010076 nsei := 2001,
Daniel Willmann423d8f42020-09-08 18:58:22 +020077 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010078 handle_sns := false,
79 nsvc := {
80 {
81 provider := {
82 ip := {
83 address_family := AF_INET,
84 local_udp_port := 21010,
85 local_ip := "127.0.0.1",
86 remote_udp_port := 23000,
87 remote_ip := "127.0.0.1"
88 }
89 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +010090 nsvci := 2101
Harald Welte90f19742020-11-06 19:34:40 +010091 }
92 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020093 },
94 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +010095 nsei := 2002,
Daniel Willmann423d8f42020-09-08 18:58:22 +020096 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010097 handle_sns := false,
98 nsvc := {
99 {
100 provider := {
101 ip := {
102 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100103 local_udp_port := 21020,
Harald Welte90f19742020-11-06 19:34:40 +0100104 local_ip := "127.0.0.1",
105 remote_udp_port := 23000,
106 remote_ip := "127.0.0.1"
107 }
108 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100109 nsvci := 2102
Harald Welte90f19742020-11-06 19:34:40 +0100110 }
111 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200112 },
113 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100114 nsei := 2003,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200115 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100116 handle_sns := false,
117 nsvc := {
118 {
119 provider := {
120 ip := {
121 address_family := AF_INET,
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100122 local_udp_port := 21030,
Harald Welte90f19742020-11-06 19:34:40 +0100123 local_ip := "127.0.0.1",
124 remote_udp_port := 23000,
125 remote_ip := "127.0.0.1"
126 }
127 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100128 nsvci := 2103
Harald Welte90f19742020-11-06 19:34:40 +0100129 }
130 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200131 }
132 };
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100133 /* BVCI are NSEI*10 + x
134 * The first NSE only has one BVC, the second one 2 and so on
135 * The Cell ID is BVCI + 10000
136 * LAC/RAC are configured in such a way that:
137 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
138 * LAC 13300 is present twice in NSE(2003)
139 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
140 * RAI 13300-0 is present twice in NSE(2003)
141 */
Harald Welte6d63f742020-11-15 19:44:04 +0100142 BssgpConfigs mp_gbconfigs := {
143 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100144 nsei := 2001,
Harald Welte6d63f742020-11-15 19:44:04 +0100145 sgsn_role := false,
146 bvc := {
147 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100148 bvci := 20011,
Harald Welte6d63f742020-11-15 19:44:04 +0100149 cell_id := {
150 ra_id := {
151 lai := {
152 mcc_mnc := c_mcc_mnc,
153 lac := 13135
154 },
155 rac := 0
156 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100157 cell_id := 30011
Harald Welte6d63f742020-11-15 19:44:04 +0100158 },
159 depth := BSSGP_DECODE_DEPTH_BSSGP,
160 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
161 }
162 }
163 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100164 nsei := 2002,
Harald Welte6d63f742020-11-15 19:44:04 +0100165 sgsn_role := false,
166 bvc := {
167 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100168 bvci := 20021,
Harald Welte6d63f742020-11-15 19:44:04 +0100169 cell_id := {
170 ra_id := {
171 lai := {
172 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100173 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100174 },
Harald Welte0e188242020-11-22 21:46:48 +0100175 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100176 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100177 cell_id := 30021
178 },
179 depth := BSSGP_DECODE_DEPTH_BSSGP,
180 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
181 },
182 {
183 bvci := 20022,
184 cell_id := {
185 ra_id := {
186 lai := {
187 mcc_mnc := c_mcc_mnc,
188 lac := 13135
189 },
190 rac := 2
191 },
192 cell_id := 30022
Harald Welte6d63f742020-11-15 19:44:04 +0100193 },
194 depth := BSSGP_DECODE_DEPTH_BSSGP,
195 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
196 }
197 }
198 }, {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100199 nsei := 2003,
Harald Welte6d63f742020-11-15 19:44:04 +0100200 sgsn_role := false,
201 bvc := {
202 {
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100203 bvci := 20031,
204 cell_id := {
205 ra_id := {
206 lai := {
207 mcc_mnc := c_mcc_mnc,
208 lac := 13135
209 },
210 rac := 1
211 },
212 cell_id := 30031
213 },
214 depth := BSSGP_DECODE_DEPTH_BSSGP,
215 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
216 },
217 {
218 bvci := 20032,
Harald Welte6d63f742020-11-15 19:44:04 +0100219 cell_id := {
220 ra_id := {
221 lai := {
222 mcc_mnc := c_mcc_mnc,
223 lac := 13300
224 },
225 rac := 0
226 },
Daniel Willmann2c9300f2020-12-01 10:54:08 +0100227 cell_id := 30032
228 },
229 depth := BSSGP_DECODE_DEPTH_BSSGP,
230 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
231 },
232 {
233 bvci := 20033,
234 cell_id := {
235 ra_id := {
236 lai := {
237 mcc_mnc := c_mcc_mnc,
238 lac := 13300
239 },
240 rac := 0
241 },
242 cell_id := 30033
Harald Welte6d63f742020-11-15 19:44:04 +0100243 },
244 depth := BSSGP_DECODE_DEPTH_BSSGP,
245 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
246 }
247 }
248 }
249 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200250};
251
Daniel Willmann423d8f42020-09-08 18:58:22 +0200252type record GbInstance {
253 NS_CT vc_NS,
254 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100255 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200256 BssgpConfig cfg
257};
Harald Welte67dc8c22020-11-17 18:32:29 +0100258type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200259
260const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100261type record of GbInstance GbInstances;
262type record of BssgpConfig BssgpConfigs;
263type record of NSConfiguration NSConfigurations;
264type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200265
266const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200267
268type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100269 var GbInstances g_pcu;
270 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200271
272 port BSSGP_CT_PROC_PT PROC;
273
Harald Weltefbae83f2020-11-15 23:25:55 +0100274 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
275 port BSSGP_BVC_MGMT_PT PCU_MGMT;
276
Daniel Willmann423d8f42020-09-08 18:58:22 +0200277 port TELNETasp_PT GBPVTY;
278
279 var boolean g_initialized := false;
280 var boolean g_use_echo := false;
Harald Welte16786e92020-11-27 19:11:56 +0100281
282 var ro_integer g_roi := {};
Harald Welte425d3762020-12-09 14:33:18 +0100283 timer g_Tguard;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200284};
285
286type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100287 /* array of per-BVC ports on the PCU side */
Harald Welte158becf2020-12-09 12:32:32 +0100288 port BSSGP_PT PCU_PTP[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200289 port BSSGP_PT PCU_SIG[NUM_PCU];
290 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100291 /* component reference to the component to which we're currently connected */
292 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100293 /* BSSGP BVC configuration of the component to which we're currently connected */
294 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100295
296 /* array of per-BVC ports on the SGSN side */
Harald Welte158becf2020-12-09 12:32:32 +0100297 port BSSGP_PT SGSN_PTP[NUM_SGSN];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200298 port BSSGP_PT SGSN_SIG[NUM_SGSN];
299 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100300 /* component reference to the component to which we're currently connected */
301 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200302
303 var BSSGP_ConnHdlrPars g_pars;
304 timer g_Tguard;
305 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100306
307 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200308}
309
310type record SGSN_ConnHdlrNetworkPars {
311 boolean expect_ptmsi,
312 boolean expect_auth,
313 boolean expect_ciph
314};
315
316type record BSSGP_ConnHdlrPars {
317 /* IMEI of the simulated ME */
318 hexstring imei,
319 /* IMSI of the simulated MS */
320 hexstring imsi,
321 /* MSISDN of the simulated MS (probably unused) */
322 hexstring msisdn,
323 /* P-TMSI allocated to the simulated MS */
324 OCT4 p_tmsi optional,
325 OCT3 p_tmsi_sig optional,
326 /* TLLI of the simulated MS */
327 OCT4 tlli,
328 OCT4 tlli_old optional,
329 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100330 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100331 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200332 float t_guard
333};
334
335private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
336 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
337 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
338
339 var RoutingAreaIdentificationV ret := {
340 mccDigit1 := mcc_mnc[0],
341 mccDigit2 := mcc_mnc[1],
342 mccDigit3 := mcc_mnc[2],
343 mncDigit3 := mcc_mnc[3],
344 mncDigit1 := mcc_mnc[4],
345 mncDigit2 := mcc_mnc[5],
346 lac := int2oct(cell_id.ra_id.lai.lac, 16),
347 rac := int2oct(cell_id.ra_id.rac, 8)
348 }
349 return ret;
350};
351
Harald Welte95339432020-12-02 18:50:52 +0100352private function f_fix_create_cb(inout BssgpConfig cfg)
353{
354 for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
355 if (not isbound(cfg.bvc[i].create_cb)) {
356 cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
357 }
358 }
359}
360
Daniel Willmann423d8f42020-09-08 18:58:22 +0200361private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100362 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
363 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
364 gb.vc_NS := NS_CT.create(ns_id);
365 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200366 /* connect lower end of BSSGP emulation with NS upper port */
367 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
368
Harald Welteb419d0e2020-11-16 16:45:05 +0100369 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
370 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200371
372 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
373 connect(self:PROC, gb.vc_BSSGP:PROC);
374 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
375 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100376 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200377 }
Harald Welte16786e92020-11-27 19:11:56 +0100378 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200379}
380
381private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100382 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
383 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
384 gb.vc_NS := NS_CT.create(ns_id);
385 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200386 /* connect lower end of BSSGP emulation with NS upper port */
387 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
388
Harald Welteb419d0e2020-11-16 16:45:05 +0100389 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
390 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200391
392 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
393 connect(self:PROC, gb.vc_BSSGP:PROC);
394 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
395 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100396 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200397 }
Harald Welte16786e92020-11-27 19:11:56 +0100398 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200399}
400
401
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100402private function f_destroy_gb(inout GbInstance gb) runs on test_CT {
403 gb.vc_NS.stop;
404 gb.vc_BSSGP.stop;
405
406 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
407 gb.vc_BSSGP_BVC[i].stop;
408 }
409}
410
Daniel Willmann423d8f42020-09-08 18:58:22 +0200411private function f_init_vty() runs on test_CT {
412 map(self:GBPVTY, system:GBPVTY);
413 f_vty_set_prompts(GBPVTY);
414 f_vty_transceive(GBPVTY, "enable");
415}
416
Harald Weltefbae83f2020-11-15 23:25:55 +0100417type record of integer ro_integer;
418
419private function ro_integer_contains(ro_integer r, integer x) return boolean {
420 for (var integer j := 0; j < lengthof(r); j := j+1) {
421 if (r[j] == x) {
422 return true;
423 }
424 }
425 return false;
426}
427
Harald Welte425d3762020-12-09 14:33:18 +0100428function f_init(float t_guard := 30.0) runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100429 var ro_integer bvci_unblocked := {};
430 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200431 var integer i;
432
433 if (g_initialized == true) {
434 return;
435 }
436 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200437
Harald Welte425d3762020-12-09 14:33:18 +0100438 g_Tguard.start(t_guard);
439 activate(as_gTguard(g_Tguard));
440
Daniel Willmann423d8f42020-09-08 18:58:22 +0200441 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100442 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200443 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100444 bvc := { }
445 }
446 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
447 g_pcu[i].cfg := mp_gbconfigs[i];
Harald Welte95339432020-12-02 18:50:52 +0100448 /* make sure all have a proper crate_cb, which cannot be specified in config file */
449 f_fix_create_cb(g_pcu[i].cfg);
Harald Welte6d63f742020-11-15 19:44:04 +0100450 /* concatenate all the PCU-side BVCs for the SGSN side */
Harald Welte95339432020-12-02 18:50:52 +0100451 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & g_pcu[i].cfg.bvc;
Harald Welte6d63f742020-11-15 19:44:04 +0100452 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200453
454 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100455 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100456 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Daniel Willmannad93c052020-12-04 14:14:38 +0100457 }
458 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
459 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
460 f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
461 }
462
463 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Harald Welteea1ba592020-11-17 18:05:13 +0100464 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100465 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200466 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100467 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100468 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100469 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100470
471 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100472 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100473 T.start;
474 alt {
475 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
476 bvci_unblocked := bvci_unblocked & { bsi.bvci };
477 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
478 repeat;
479 }
480 }
481 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
482 repeat;
483 }
Harald Welte3c905152020-11-26 20:56:09 +0100484 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
485 repeat;
486 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100487 [] SGSN_MGMT.receive {
488 setverdict(fail, "Received unexpected message on SGSN_MGMT");
489 mtc.stop;
490 }
491
492 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
493 repeat;
494 }
495 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
496 repeat;
497 }
498 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
499 repeat;
500 }
501 [] PCU_MGMT.receive {
502 setverdict(fail, "Received unexpected message on PCU_MGMT");
503 mtc.stop;
504 }
505
506 [] T.timeout {
Harald Welte6929e322020-12-12 13:10:45 +0100507 setverdict(fail, "Timeout waiting for unblock of all BVCs on SGSN side; ",
508 "unblocked so far: ", bvci_unblocked, "expected: ", g_sgsn[0].cfg.bvc);
509 /* don't stop here but print below analysis */
Harald Weltefbae83f2020-11-15 23:25:55 +0100510 }
511 }
512
513 /* iterate over list and check all BVCI */
514 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
515 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
516 if (not ro_integer_contains(bvci_unblocked, bvci)) {
517 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
518 mtc.stop;
519 }
520 }
Harald Welte425d3762020-12-09 14:33:18 +0100521
522 /* re-start guard timer after all BVCs are up, so it only counts the actual test case */
523 g_Tguard.start(t_guard);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200524}
525
526function f_cleanup() runs on test_CT {
Harald Welteb9f0fdc2020-12-09 14:44:50 +0100527 var integer i;
528
529 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
530 f_destroy_gb(g_sgsn[i]);
531 }
532 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
533 f_destroy_gb(g_pcu[i]);
534 }
535
536 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200537}
538
539type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
540
541/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100542function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200543 float t_guard := 30.0)
544runs on test_CT return BSSGP_ConnHdlr {
545 var BSSGP_ConnHdlr vc_conn;
546
547 var BSSGP_ConnHdlrPars pars := {
548 imei := f_gen_imei(imsi_suffix),
549 imsi := f_gen_imsi(imsi_suffix),
550 msisdn := f_gen_msisdn(imsi_suffix),
551 p_tmsi := omit,
552 p_tmsi_sig := omit,
553 tlli := f_gprs_tlli_random(),
554 tlli_old := omit,
555 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100556 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100557 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200558 t_guard := t_guard
559 };
560
561 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200562
563 vc_conn.start(f_handler_init(fn, id, pars));
564 return vc_conn;
565}
566
Harald Welte3dd21b32020-11-17 19:21:00 +0100567/* 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 +0100568private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
569runs on BSSGP_ConnHdlr {
570 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte158becf2020-12-09 12:32:32 +0100571 if (PCU_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100572 /* unregister + disconnect from old BVC */
573 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100574 disconnect(self:PCU_PTP[port_idx], pcu_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100575 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
576 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
577 }
578 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100579 connect(self:PCU_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100580 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
581 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
582 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
583 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100584 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100585}
586
587/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
588private 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 +0100589 if (SGSN_PTP[port_idx].checkstate("Connected")) {
Harald Welte3dd21b32020-11-17 19:21:00 +0100590 /* unregister + disconnect from old BVC */
591 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
Harald Welte158becf2020-12-09 12:32:32 +0100592 disconnect(self:SGSN_PTP[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100593 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
594 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
595 }
596 /* connect to new BVC and register us */
Harald Welte158becf2020-12-09 12:32:32 +0100597 connect(self:SGSN_PTP[port_idx], bvc_ct:BSSGP_SP);
Harald Welte3dd21b32020-11-17 19:21:00 +0100598 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
599 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
600 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
601 sgsn_ct[port_idx] := bvc_ct;
602}
603
Harald Welte425d3762020-12-09 14:33:18 +0100604private altstep as_gTguard(timer Tguard) {
605 [] Tguard.timeout {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200606 setverdict(fail, "Tguard timeout");
607 mtc.stop;
608 }
609}
610
611/* first function called in every ConnHdlr */
612private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
613runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100614 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200615 /* do some common stuff like setting up g_pars */
616 g_pars := pars;
617
618 llc := f_llc_create(false);
619
Harald Welte3dd21b32020-11-17 19:21:00 +0100620 /* default connections on PCU side: First BVC of each NSE/PCU */
621 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100622 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100623 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100624
625 /* default connections on SGSN side: First BVC of each NSE/SGSN */
626 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
627 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100628 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200629
630 g_Tguard.start(pars.t_guard);
Harald Welte425d3762020-12-09 14:33:18 +0100631 activate(as_gTguard(g_Tguard));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200632
633 /* call the user-supplied test case function */
634 fn.apply(id);
635}
636
Harald Welte1e834f32020-11-15 20:02:59 +0100637private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
638runs on BSSGP_ConnHdlr {
639 PT.call(BSSGP_register_client:{imsi, tlli}) {
640 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
641 }
642}
643
644private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
645runs on BSSGP_ConnHdlr {
646 PT.call(BSSGP_unregister_client:{imsi}) {
647 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
648 }
649}
650
Harald Welte22ef5d92020-11-16 13:35:14 +0100651/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
652friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100653 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100654 var PDU_BSSGP rx;
655 timer T := 1.0;
656
Daniel Willmann4798fd72020-11-24 16:23:29 +0100657 if (use_sig) {
658 PCU_SIG[pcu_idx].send(tx);
659 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100660 PCU_PTP[pcu_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100661 }
662
Harald Welte22ef5d92020-11-16 13:35:14 +0100663 T.start;
664 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100665 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
666 setverdict(pass);
667 }
Harald Welte158becf2020-12-09 12:32:32 +0100668 [not use_sig] SGSN_PTP[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100669 setverdict(pass);
670 }
Harald Welte158becf2020-12-09 12:32:32 +0100671 [] SGSN_PTP[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100672 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
673 mtc.stop;
674 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100675 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
676 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
677 mtc.stop;
678 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100679 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100680 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100681 mtc.stop;
682 }
683 }
684}
685
686/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
687friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100688 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100689 var PDU_BSSGP rx;
690 timer T := 1.0;
691
Daniel Willmann4798fd72020-11-24 16:23:29 +0100692 if (use_sig) {
693 SGSN_SIG[sgsn_idx].send(tx);
694 } else {
Harald Welte158becf2020-12-09 12:32:32 +0100695 SGSN_PTP[sgsn_idx].send(tx);
Daniel Willmann4798fd72020-11-24 16:23:29 +0100696 }
697
Harald Welte22ef5d92020-11-16 13:35:14 +0100698 T.start;
699 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100700 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
701 setverdict(pass);
702 }
Harald Welte158becf2020-12-09 12:32:32 +0100703 [not use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100704 setverdict(pass);
705 }
Harald Welte158becf2020-12-09 12:32:32 +0100706 [] PCU_PTP[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
Harald Welte22ef5d92020-11-16 13:35:14 +0100707 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
708 mtc.stop;
709 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100710 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
711 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
712 mtc.stop;
713 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100714 [] T.timeout {
Harald Welte8b326412020-11-29 16:05:38 +0100715 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte22ef5d92020-11-16 13:35:14 +0100716 mtc.stop;
717 }
718 }
719}
Harald Welte1e834f32020-11-15 20:02:59 +0100720
Harald Welte3807ed12020-11-24 19:05:22 +0100721/***********************************************************************
722 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
723 ***********************************************************************/
724
725type component GlobalTest_CT extends test_CT {
726 port BSSGP_PT G_PCU[NUM_PCU];
727 port BSSGP_PT G_SGSN[NUM_SGSN];
728};
729
Harald Welte299aa482020-12-09 15:10:55 +0100730/* connect the signaling BVC of each NSE to the G_PCU / G_SGSN ports */
Harald Welte3807ed12020-11-24 19:05:22 +0100731private function f_global_init() runs on GlobalTest_CT {
732 var integer i;
733 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
734 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
735 }
736 for (i := 0; i < lengthof(g_pcu); i := i+1) {
737 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
738 }
739}
740
Harald Welte299aa482020-12-09 15:10:55 +0100741/* connect the first PTP BVC of each NSE to the G_PCU / G_SGSN ports */
742private function f_global_init_ptp() runs on GlobalTest_CT {
743 var integer i;
744 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
745 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP_BVC[0]:GLOBAL);
746 }
747 for (i := 0; i < lengthof(g_pcu); i := i+1) {
748 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP_BVC[0]:GLOBAL);
749 }
750}
751
Harald Welte3807ed12020-11-24 19:05:22 +0100752/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
753friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
754 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
755 var PDU_BSSGP rx;
756 timer T := 1.0;
757
758 G_PCU[pcu_idx].send(tx);
759 T.start;
760 alt {
761 [] G_SGSN[sgsn_idx].receive(exp_rx) {
762 setverdict(pass);
763 }
764 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
765 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
766 mtc.stop;
767 }
768 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100769 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100770 mtc.stop;
771 }
772 }
773}
774
775/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
776friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
777 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
778 var PDU_BSSGP rx;
779 timer T := 1.0;
780
781 G_SGSN[sgsn_idx].send(tx);
782 T.start;
783 alt {
784 [] G_PCU[pcu_idx].receive(exp_rx) {
785 setverdict(pass);
786 }
787 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
788 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
789 mtc.stop;
790 }
791 [] T.timeout {
Harald Weltedc805c02020-12-11 10:59:17 +0100792 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
Harald Welte3807ed12020-11-24 19:05:22 +0100793 mtc.stop;
794 }
795 }
796}
797
798
Daniel Willmann423d8f42020-09-08 18:58:22 +0200799/* TODO:
800 * Detach without Attach
801 * SM procedures without attach / RAU
802 * ATTACH / RAU
803 ** with / without authentication
804 ** with / without P-TMSI allocation
805 * re-transmissions of LLC frames
806 * PDP Context activation
807 ** with different GGSN config in SGSN VTY
808 ** with different PDP context type (v4/v6/v46)
809 ** timeout from GGSN
810 ** multiple / secondary PDP context
811 */
812
813private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
814 f_sleep(5.0);
815 setverdict(pass);
816}
817
818testcase TC_BVC_bringup() runs on test_CT {
819 var BSSGP_ConnHdlr vc_conn;
820 f_init();
821
822 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
823 vc_conn.done;
824
825 f_cleanup();
826}
827
828friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100829 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200830 timer T := 5.0;
831 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100832 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200833 T.start;
834 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100835 [] 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 +0200836 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
837 }
Harald Welte16357a92020-11-17 18:20:00 +0100838 [] 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 +0200839 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
840 mtc.stop;
841 }
842 [] T.timeout {
843 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
844 mtc.stop;
845 }
846 }
847 return '00'O;
848}
849
850friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100851 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200852 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100853 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 +0200854 T.start;
855 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100856 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
857 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200858 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
859 mtc.stop;
860 }
861 [] T.timeout {
862 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
863 mtc.stop;
864 }
865 }
866}
867
868
Harald Welte92686012020-11-15 21:45:49 +0100869/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
870private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100871 var integer ran_idx := 0;
872 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100873 var integer i;
874
Harald Welte0d5fceb2020-11-29 16:04:07 +0100875 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte92686012020-11-15 21:45:49 +0100876 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100877 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 +0100878 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100879 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 +0100880
Harald Welte0d5fceb2020-11-29 16:04:07 +0100881 log("UL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100882 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100883 }
884 setverdict(pass);
885}
886
887testcase TC_ul_unitdata() runs on test_CT
888{
889 var BSSGP_ConnHdlr vc_conn;
890 f_init();
891
892 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
893 vc_conn.done;
894 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
895
896 f_cleanup();
897}
898
Harald Welte78d8db92020-11-15 23:27:27 +0100899/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
900private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
901 var integer i;
902
Harald Welte0d5fceb2020-11-29 16:04:07 +0100903 for (i := 0; i < max_fr_info_size-4; i := i+4) {
Harald Welte78d8db92020-11-15 23:27:27 +0100904 var octetstring payload := f_rnd_octstring(i);
905 var template (value) PDU_BSSGP pdu_tx :=
906 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
907 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
908 var template (present) PDU_BSSGP pdu_rx :=
909 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
910
Harald Welte0d5fceb2020-11-29 16:04:07 +0100911 log("DL-UNITDATA(payload_size=", i);
Harald Welte22ef5d92020-11-16 13:35:14 +0100912 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100913 }
914 setverdict(pass);
915}
916
917testcase TC_dl_unitdata() runs on test_CT
918{
919 var BSSGP_ConnHdlr vc_conn;
920 f_init();
921
922 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
923 vc_conn.done;
924 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
925
926 f_cleanup();
927}
Harald Welte92686012020-11-15 21:45:49 +0100928
Harald Welte6dc2ac42020-11-16 09:16:17 +0100929private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
930 var integer i;
931
932 for (i := 0; i < 10; i := i+1) {
933 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
934 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
935 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
936
Harald Welte22ef5d92020-11-16 13:35:14 +0100937 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100938 }
939 setverdict(pass);
940}
941testcase TC_ra_capability() runs on test_CT
942{
943 var BSSGP_ConnHdlr vc_conn;
944 f_init();
945
946 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
947 vc_conn.done;
948 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
949
950 f_cleanup();
951}
952
Daniel Willmannace3ece2020-11-16 19:53:26 +0100953private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
954 var integer i;
955 var OCT1 tag;
956 for (i := 0; i < 10; i := i+1) {
957 tag := int2oct(23 + i, 1);
958 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
959 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
960 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
961
962 f_pcu2sgsn(pdu_tx, pdu_rx);
963
964 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
965 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
966 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
967
968 f_sgsn2pcu(pdu_tx, pdu_rx);
969 }
970 setverdict(pass);
971}
972testcase TC_ra_capability_upd() runs on test_CT
973{
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976
Daniel Willmann54833f22020-11-19 15:43:52 +0100977 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100978 vc_conn.done;
979 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
980
981 f_cleanup();
982}
983
Daniel Willmann165d6612020-11-19 14:27:29 +0100984private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
985 var integer i;
986 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
987 for (i := 0; i < 10; i := i+1) {
988 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
989 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
990 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
991
992 f_pcu2sgsn(pdu_tx, pdu_rx);
993 }
994 setverdict(pass);
995}
996testcase TC_radio_status() runs on test_CT
997{
998 var BSSGP_ConnHdlr vc_conn;
999 f_init();
1000
Daniel Willmann54833f22020-11-19 15:43:52 +01001001 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +01001002 vc_conn.done;
1003 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1004
1005 f_cleanup();
1006}
1007
Harald Welte3807ed12020-11-24 19:05:22 +01001008private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +01001009 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +01001010
Daniel Willmannfa67f492020-11-19 15:48:05 +01001011 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001012 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +01001013 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001014 var OCT4 tlli := f_gprs_tlli_random();
1015 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001016 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001017 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001018
Harald Welte3807ed12020-11-24 19:05:22 +01001019 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001020
Harald Welte3807ed12020-11-24 19:05:22 +01001021 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001022 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001023 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +01001024
Harald Welte3807ed12020-11-24 19:05:22 +01001025 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001026
1027 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001028 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001029 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001030 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001031
Harald Welte3807ed12020-11-24 19:05:22 +01001032 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +01001033 }
1034 setverdict(pass);
1035}
Harald Welte3807ed12020-11-24 19:05:22 +01001036testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +01001037{
Daniel Willmannfa67f492020-11-19 15:48:05 +01001038 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001039 f_global_init();
1040 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +01001041 f_cleanup();
1042}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001043
Harald Welte3807ed12020-11-24 19:05:22 +01001044private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +01001045 var integer i;
1046
1047 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +01001048 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +01001049 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +01001050 var OCT4 tlli := f_gprs_tlli_random();
1051 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001052 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001053 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +01001054
Harald Welte3807ed12020-11-24 19:05:22 +01001055 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001056
Harald Welte3807ed12020-11-24 19:05:22 +01001057 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001058 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001059 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001060
Harald Welte3807ed12020-11-24 19:05:22 +01001061 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001062
1063 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +01001064 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001065 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +01001066 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001067
Harald Welte3807ed12020-11-24 19:05:22 +01001068 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +01001069 }
1070 setverdict(pass);
1071}
Harald Welte3807ed12020-11-24 19:05:22 +01001072testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +01001073{
Daniel Willmann087a33d2020-11-19 15:58:43 +01001074 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +01001075 f_global_init();
1076 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +01001077 f_cleanup();
1078}
1079
Harald Weltef8ef0282020-11-18 12:16:59 +01001080/* test the load-sharing between multiple NS-VC on the BSS side */
1081private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
1082 var integer i;
1083
1084 for (i := 0; i < 10; i := i+1) {
1085 var octetstring payload := f_rnd_octstring(i);
1086 var template (value) PDU_BSSGP pdu_tx :=
1087 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
Harald Welte158becf2020-12-09 12:32:32 +01001088 SGSN_PTP[0].send(pdu_tx);
Harald Weltef8ef0282020-11-18 12:16:59 +01001089 }
1090 setverdict(pass);
1091}
1092testcase TC_load_sharing_dl() runs on test_CT_NS
1093{
1094 const integer num_ue := 10;
1095 var BSSGP_ConnHdlr vc_conn[num_ue];
1096 f_init();
1097
1098 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
1099 * side so we get the raw NsUnitdataIndication and hence observe different
1100 * NSVCI */
1101 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
1102 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
1103
1104 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
1105 * of the NS-VC is ALIVE/UNBLOCKED */
1106 f_sleep(3.0);
1107
1108 /* start parallel components generating DL-UNITDATA from the SGSN side */
1109 for (var integer i:= 0; i < num_ue; i := i+1) {
1110 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
1111 }
1112
1113 /* now start counting all the messages that were queued before */
1114 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
1115 var ro_integer rx_count := { 0, 0, 0, 0 };
1116 timer T := 2.0;
1117 T.start;
1118 alt {
1119 [] as_NsUdiCount(0, rx_count);
1120 [] as_NsUdiCount(1, rx_count);
1121 [] as_NsUdiCount(2, rx_count);
1122 [] as_NsUdiCount(3, rx_count);
1123 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1124 [] NS.receive(NsStatusIndication:?) { repeat; }
1125 [] NS.receive {
1126 setverdict(fail, "Rx unexpected NS");
1127 mtc.stop;
1128 }
1129 [] T.timeout {
1130 }
1131 }
1132 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1133 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1134 if (rx_count[i] == 0) {
1135 setverdict(fail, "Data not shared over all NSVC");
1136 }
1137 }
1138 setverdict(pass);
1139}
1140private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1141 var NsUnitdataIndication udi;
1142 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1143 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1144 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1145 repeat;
1146 }
1147}
1148type component test_CT_NS extends test_CT {
1149 port NS_PT NS;
1150};
1151
1152
Harald Welte0e188242020-11-22 21:46:48 +01001153/***********************************************************************
1154 * PAGING PS procedure
1155 ***********************************************************************/
1156
1157private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1158 boolean use_sig := false)
1159runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1160 var template (value) PDU_BSSGP pdu_tx;
1161 var template (present) PDU_BSSGP pdu_rx;
1162 /* we always specify '0' as BVCI in the templates below, as we override it with
1163 * 'p4' later anyway */
1164 pdu_rx := tr_BSSGP_PS_PAGING(0);
1165 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1166 if (ispresent(g_pars.p_tmsi)) {
1167 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1168 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1169 } else {
1170 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1171 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1172 }
1173 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1174 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1175 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001176 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001177 } else {
1178 SGSN_SIG[sgsn_idx].send(pdu_tx);
1179 }
1180 return pdu_rx;
1181}
1182
1183/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1184 * specified PCU index */
1185private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1186 boolean use_sig := false,integer pcu_idx := 0)
1187runs on BSSGP_ConnHdlr {
1188 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001189 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001190 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1191 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1192 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1193 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1194 timer T := 2.0;
1195 T.start;
1196 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001197 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001198 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001199 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001200 repeat;
1201 }
1202 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1203 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1204 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001205 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001206 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001207 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001208 repeat;
1209 }
Harald Welte158becf2020-12-09 12:32:32 +01001210 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001211 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1212 }
Harald Welte158becf2020-12-09 12:32:32 +01001213 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001214 setverdict(fail, "Paging received on unexpected BVC");
1215 }
1216 [] any from PCU_SIG.receive(exp_rx) {
1217 setverdict(fail, "Paging received on unexpected BVC");
1218 }
Harald Welte158becf2020-12-09 12:32:32 +01001219 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001220 setverdict(fail, "Different Paging than expected received PTP BVC");
1221 }
1222 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1223 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1224 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001225 [not test_done] T.timeout {
1226 setverdict(fail, "Timeout waiting for paging");
1227 }
1228 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001229 }
1230}
1231
Harald Welte7462a592020-11-23 22:07:07 +01001232/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1233private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1234 boolean use_sig := false)
1235runs on BSSGP_ConnHdlr {
1236 var template (present) PDU_BSSGP exp_rx;
1237 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1238 /* Expect paging to propagate to no BSS */
1239 timer T := 2.0;
1240 T.start;
1241 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001242 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001243 setverdict(fail, "Paging received on unexpected BVC");
1244 }
1245 [] any from PCU_SIG.receive(exp_rx) {
1246 setverdict(fail, "Paging received on unexpected BVC");
1247 }
Harald Welte158becf2020-12-09 12:32:32 +01001248 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001249 setverdict(fail, "Different Paging received on PTP BVC");
1250 }
1251 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1252 setverdict(fail, "Different Paging received on SIGNALING BVC");
1253 }
1254 [] T.timeout {
1255 setverdict(pass);
1256 }
1257 }
1258}
1259
Harald Welte0e188242020-11-22 21:46:48 +01001260private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1261{
1262 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1263 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1264 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1265}
1266testcase TC_paging_ps_ptp_bss() runs on test_CT {
1267 var BSSGP_ConnHdlr vc_conn;
1268 f_init();
1269
1270 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1271 vc_conn.done;
1272
1273 f_cleanup();
1274}
1275
1276/* PS-PAGING on PTP-BVC for Location Area */
1277private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1278{
1279 var template (present) PDU_BSSGP exp_rx;
1280 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1281 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1282 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1283}
1284testcase TC_paging_ps_ptp_lac() runs on test_CT {
1285 var BSSGP_ConnHdlr vc_conn;
1286 f_init();
1287
1288 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1289 vc_conn.done;
1290
1291 f_cleanup();
1292}
1293
Harald Welte7462a592020-11-23 22:07:07 +01001294/* PS-PAGING on PTP-BVC for unknown Location Area */
1295private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1296{
1297 var GSM_Types.LocationAreaIdentification unknown_la := {
1298 mcc_mnc := '567F99'H,
1299 lac := 33333
1300 };
1301 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1302 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1303}
1304testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1305 var BSSGP_ConnHdlr vc_conn;
1306 f_init();
1307
1308 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1309 vc_conn.done;
1310
1311 f_cleanup();
1312}
1313
Harald Welte0e188242020-11-22 21:46:48 +01001314/* PS-PAGING on PTP-BVC for Routeing Area */
1315private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1316{
1317 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1318 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1319 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1320}
1321testcase TC_paging_ps_ptp_rac() runs on test_CT {
1322 var BSSGP_ConnHdlr vc_conn;
1323 f_init();
1324
1325 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1326 vc_conn.done;
1327
1328 f_cleanup();
1329}
1330
Harald Welte7462a592020-11-23 22:07:07 +01001331/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1332private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1333{
1334 var RoutingAreaIdentification unknown_ra := {
1335 lai := {
1336 mcc_mnc := '567F99'H,
1337 lac := 33333
1338 },
1339 rac := 254
1340 };
1341 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1342 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1343}
1344testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1345 var BSSGP_ConnHdlr vc_conn;
1346 f_init();
1347
1348 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1349 vc_conn.done;
1350
1351 f_cleanup();
1352}
1353
Harald Welte0e188242020-11-22 21:46:48 +01001354/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1355private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1356{
1357 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1358 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1359}
1360testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1361 var BSSGP_ConnHdlr vc_conn;
1362 f_init();
1363
1364 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1365 vc_conn.done;
1366
1367 f_cleanup();
1368}
1369
Harald Welte7462a592020-11-23 22:07:07 +01001370/* PS-PAGING on PTP-BVC for unknown BVCI */
1371private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1372{
1373 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1374 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1375}
1376testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1377 var BSSGP_ConnHdlr vc_conn;
1378 f_init();
1379
1380 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1381 vc_conn.done;
1382
1383 f_cleanup();
1384}
1385
Harald Welte0e188242020-11-22 21:46:48 +01001386/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1387private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1388runs on BSSGP_ConnHdlr {
1389[] PCU_SIG[pcu_idx].receive(exp_rx) {
1390 if (ro_integer_contains(roi, pcu_idx)) {
1391 setverdict(fail, "Received multiple paging on same SIG BVC");
1392 }
1393 roi := roi & { pcu_idx };
1394 repeat;
1395 }
Harald Welte158becf2020-12-09 12:32:32 +01001396[] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001397 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1398 }
1399[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1400 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1401 }
Harald Welte158becf2020-12-09 12:32:32 +01001402[] PCU_PTP[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001403 setverdict(fail, "Different Paging than expected received PTP BVC");
1404 }
1405}
1406
1407type record of default ro_default;
1408
1409/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1410private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1411 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1412{
1413 var template (present) PDU_BSSGP exp_rx;
1414 exp_rx := f_send_paging_ps(p4, 0, true);
1415
1416 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1417 var ro_default defaults := {};
1418 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1419 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1420 defaults := defaults & { d };
1421 }
1422 f_sleep(2.0);
1423 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1424 deactivate(defaults[i]);
1425 }
1426 log("Paging received on PCU ", g_roi);
1427
1428 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1429 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1430 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1431 if (exp_on_i and not rx_on_i) {
1432 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1433 }
1434 if (not exp_on_i and rx_on_i) {
1435 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1436 }
1437 }
1438 setverdict(pass);
1439}
1440
1441/* PS-PAGING on SIG-BVC for BSS Area */
1442private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1443{
1444 /* we expect the paging to arrive on all three NSE */
1445 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1446}
1447testcase TC_paging_ps_sig_bss() runs on test_CT {
1448 var BSSGP_ConnHdlr vc_conn;
1449 f_init();
1450
1451 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1452 vc_conn.done;
1453
1454 f_cleanup();
1455}
1456
1457/* PS-PAGING on SIG-BVC for Location Area */
1458private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1459{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001460 /* The first LAC (13135) is shared by all three NSEs */
1461 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1462 /* Reset state */
1463 g_roi := {};
1464 /* Make LAC (13300) available on pcu index 2 */
1465 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1466 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 +01001467}
1468testcase TC_paging_ps_sig_lac() runs on test_CT {
1469 var BSSGP_ConnHdlr vc_conn;
1470 f_init();
1471
1472 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1473 vc_conn.done;
1474
1475 f_cleanup();
1476}
1477
Harald Welte7462a592020-11-23 22:07:07 +01001478/* PS-PAGING on SIG-BVC for unknown Location Area */
1479private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1480{
1481 var GSM_Types.LocationAreaIdentification unknown_la := {
1482 mcc_mnc := '567F99'H,
1483 lac := 33333
1484 };
1485 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1486}
1487testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1488 var BSSGP_ConnHdlr vc_conn;
1489 f_init();
1490
1491 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1492 vc_conn.done;
1493
1494 f_cleanup();
1495}
1496
Harald Welte0e188242020-11-22 21:46:48 +01001497/* PS-PAGING on SIG-BVC for Routeing Area */
1498private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1499{
Daniel Willmann2c9300f2020-12-01 10:54:08 +01001500 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001501 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 +01001502 g_roi := {};
1503 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1504 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1505 g_roi := {};
1506 /* PCU index 2 has two matching BVCs with the RA ID */
1507 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1508 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 +01001509}
1510testcase TC_paging_ps_sig_rac() runs on test_CT {
1511 var BSSGP_ConnHdlr vc_conn;
1512 f_init();
1513
1514 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1515 vc_conn.done;
1516
1517 f_cleanup();
1518}
1519
Harald Welte7462a592020-11-23 22:07:07 +01001520/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1521private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1522{
1523 var RoutingAreaIdentification unknown_ra := {
1524 lai := {
1525 mcc_mnc := '567F99'H,
1526 lac := 33333
1527 },
1528 rac := 254
1529 };
1530 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1531}
1532testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1533 var BSSGP_ConnHdlr vc_conn;
1534 f_init();
1535
1536 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1537 vc_conn.done;
1538
1539 f_cleanup();
1540}
1541
Harald Welte0e188242020-11-22 21:46:48 +01001542/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1543private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1544{
1545 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1546}
1547testcase TC_paging_ps_sig_bvci() runs on test_CT {
1548 var BSSGP_ConnHdlr vc_conn;
1549 f_init();
1550
1551 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1552 vc_conn.done;
1553
1554 f_cleanup();
1555}
1556
Harald Welte7462a592020-11-23 22:07:07 +01001557/* PS-PAGING on SIG-BVC for unknown BVCI */
1558private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1559{
1560 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1561}
1562testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1563 var BSSGP_ConnHdlr vc_conn;
1564 f_init();
1565
1566 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1567 vc_conn.done;
1568
1569 f_cleanup();
1570}
1571
1572
Harald Welte0e188242020-11-22 21:46:48 +01001573
1574/***********************************************************************
1575 * PAGING CS procedure
1576 ***********************************************************************/
1577
1578private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1579 boolean use_sig := false)
1580runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1581 var template (value) PDU_BSSGP pdu_tx;
1582 var template (present) PDU_BSSGP pdu_rx;
1583 /* we always specify '0' as BVCI in the templates below, as we override it with
1584 * 'p4' later anyway */
1585 pdu_rx := tr_BSSGP_CS_PAGING(0);
1586 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1587 if (ispresent(g_pars.p_tmsi)) {
1588 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1589 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1590 } else {
1591 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1592 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1593 }
1594 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1595 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1596 if (use_sig == false) {
Harald Welte158becf2020-12-09 12:32:32 +01001597 SGSN_PTP[sgsn_idx].send(pdu_tx);
Harald Welte0e188242020-11-22 21:46:48 +01001598 } else {
1599 SGSN_SIG[sgsn_idx].send(pdu_tx);
1600 }
1601 return pdu_rx;
1602}
1603
1604/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1605 * specified PCU index */
1606private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1607 boolean use_sig := false,integer pcu_idx := 0)
1608runs on BSSGP_ConnHdlr {
1609 var template (present) PDU_BSSGP exp_rx;
Daniel Willmann1a859712020-12-04 00:59:45 +01001610 var boolean test_done := false;
Harald Welte0e188242020-11-22 21:46:48 +01001611 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1612 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1613 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1614 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1615 timer T := 2.0;
1616 T.start;
1617 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001618 [not use_sig and not test_done] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001619 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001620 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001621 repeat;
1622 }
1623 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1624 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1625 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001626 [use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001627 setverdict(pass);
Daniel Willmann1a859712020-12-04 00:59:45 +01001628 test_done := true;
Harald Welte0e188242020-11-22 21:46:48 +01001629 repeat;
1630 }
Harald Welte158becf2020-12-09 12:32:32 +01001631 [use_sig] PCU_PTP[pcu_idx].receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001632 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1633 }
Harald Welte158becf2020-12-09 12:32:32 +01001634 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte0e188242020-11-22 21:46:48 +01001635 setverdict(fail, "Paging received on unexpected BVC");
1636 }
1637 [] any from PCU_SIG.receive(exp_rx) {
1638 setverdict(fail, "Paging received on unexpected BVC");
1639 }
Harald Welte158becf2020-12-09 12:32:32 +01001640 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte0e188242020-11-22 21:46:48 +01001641 setverdict(fail, "Different Paging than expected received PTP BVC");
1642 }
1643 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1644 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1645 }
Daniel Willmann1a859712020-12-04 00:59:45 +01001646 [not test_done] T.timeout {
1647 setverdict(fail, "Timeout while waiting for paging")
1648 }
1649 [test_done] T.timeout;
Harald Welte0e188242020-11-22 21:46:48 +01001650 }
1651}
1652
Harald Welte7462a592020-11-23 22:07:07 +01001653/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1654private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1655 boolean use_sig := false)
1656runs on BSSGP_ConnHdlr {
1657 var template (present) PDU_BSSGP exp_rx;
1658 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1659 /* Expect paging to propagate to no BSS */
1660 timer T := 2.0;
1661 T.start;
1662 alt {
Harald Welte158becf2020-12-09 12:32:32 +01001663 [] any from PCU_PTP.receive(exp_rx) {
Harald Welte7462a592020-11-23 22:07:07 +01001664 setverdict(fail, "Paging received on unexpected BVC");
1665 }
1666 [] any from PCU_SIG.receive(exp_rx) {
1667 setverdict(fail, "Paging received on unexpected BVC");
1668 }
Harald Welte158becf2020-12-09 12:32:32 +01001669 [] any from PCU_PTP.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
Harald Welte7462a592020-11-23 22:07:07 +01001670 setverdict(fail, "Different Paging received on PTP BVC");
1671 }
1672 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1673 setverdict(fail, "Different Paging received on SIGNALING BVC");
1674 }
1675 [] T.timeout {
1676 setverdict(pass);
1677 }
1678 }
1679}
1680
Harald Welte0e188242020-11-22 21:46:48 +01001681private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1682{
1683 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1684 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1685 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1686}
1687testcase TC_paging_cs_ptp_bss() runs on test_CT {
1688 var BSSGP_ConnHdlr vc_conn;
1689 f_init();
1690
1691 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1692 vc_conn.done;
1693
1694 f_cleanup();
1695}
1696
1697/* CS-PAGING on PTP-BVC for Location Area */
1698private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1699{
1700 var template (present) PDU_BSSGP exp_rx;
1701 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1702 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1703 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1704}
1705testcase TC_paging_cs_ptp_lac() runs on test_CT {
1706 var BSSGP_ConnHdlr vc_conn;
1707 f_init();
1708
1709 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1710 vc_conn.done;
1711
1712 f_cleanup();
1713}
1714
Harald Welte7462a592020-11-23 22:07:07 +01001715/* CS-PAGING on PTP-BVC for unknown Location Area */
1716private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1717{
1718 var GSM_Types.LocationAreaIdentification unknown_la := {
1719 mcc_mnc := '567F99'H,
1720 lac := 33333
1721 };
1722 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1723 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1724}
1725testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1726 var BSSGP_ConnHdlr vc_conn;
1727 f_init();
1728
1729 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1730 vc_conn.done;
1731
1732 f_cleanup();
1733}
1734
Harald Welte0e188242020-11-22 21:46:48 +01001735/* CS-PAGING on PTP-BVC for Routeing Area */
1736private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1737{
1738 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1739 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1740 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1741}
1742testcase TC_paging_cs_ptp_rac() runs on test_CT {
1743 var BSSGP_ConnHdlr vc_conn;
1744 f_init();
1745
1746 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1747 vc_conn.done;
1748
1749 f_cleanup();
1750}
1751
Harald Welte7462a592020-11-23 22:07:07 +01001752/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1753private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1754{
1755 var RoutingAreaIdentification unknown_ra := {
1756 lai := {
1757 mcc_mnc := '567F99'H,
1758 lac := 33333
1759 },
1760 rac := 254
1761 };
1762 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1763 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1764}
1765testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1766 var BSSGP_ConnHdlr vc_conn;
1767 f_init();
1768
1769 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1770 vc_conn.done;
1771
1772 f_cleanup();
1773}
1774
Harald Welte0e188242020-11-22 21:46:48 +01001775/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1776private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1777{
1778 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1779 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1780}
1781testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1782 var BSSGP_ConnHdlr vc_conn;
1783 f_init();
1784
1785 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1786 vc_conn.done;
1787
1788 f_cleanup();
1789}
1790
Harald Welte7462a592020-11-23 22:07:07 +01001791/* CS-PAGING on PTP-BVC for unknown BVCI */
1792private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1793{
1794 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1795 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1796}
1797testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1798 var BSSGP_ConnHdlr vc_conn;
1799 f_init();
1800
1801 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1802 vc_conn.done;
1803
1804 f_cleanup();
1805}
1806
Harald Welte0e188242020-11-22 21:46:48 +01001807/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1808private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1809 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1810{
1811 var template (present) PDU_BSSGP exp_rx;
1812 exp_rx := f_send_paging_cs(p4, 0, true);
1813
1814 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1815 var ro_default defaults := {};
1816 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1817 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1818 defaults := defaults & { d };
1819 }
1820 f_sleep(2.0);
1821 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1822 deactivate(defaults[i]);
1823 }
1824 log("Paging received on PCU ", g_roi);
1825
1826 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1827 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1828 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1829 if (exp_on_i and not rx_on_i) {
1830 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1831 }
1832 if (not exp_on_i and rx_on_i) {
1833 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1834 }
1835 }
1836 setverdict(pass);
1837}
1838
1839/* CS-PAGING on SIG-BVC for BSS Area */
1840private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1841{
1842 /* we expect the paging to arrive on all three NSE */
1843 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1844}
1845testcase TC_paging_cs_sig_bss() runs on test_CT {
1846 var BSSGP_ConnHdlr vc_conn;
1847 f_init();
1848
1849 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1850 vc_conn.done;
1851
1852 f_cleanup();
1853}
1854
1855/* CS-PAGING on SIG-BVC for Location Area */
1856private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1857{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001858 /* The first LAC (13135) is shared by all three NSEs */
1859 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
1860 /* Reset state */
1861 g_roi := {};
1862 /* Make LAC (13300) available on pcu index 2 */
1863 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1864 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 +01001865}
1866testcase TC_paging_cs_sig_lac() runs on test_CT {
1867 var BSSGP_ConnHdlr vc_conn;
1868 f_init();
1869
1870 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1871 vc_conn.done;
1872
1873 f_cleanup();
1874}
1875
Harald Welte7462a592020-11-23 22:07:07 +01001876/* CS-PAGING on SIG-BVC for unknown Location Area */
1877private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1878{
1879 var GSM_Types.LocationAreaIdentification unknown_la := {
1880 mcc_mnc := '567F99'H,
1881 lac := 33333
1882 };
1883 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1884}
1885testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1886 var BSSGP_ConnHdlr vc_conn;
1887 f_init();
1888
1889 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1890 vc_conn.done;
1891
1892 f_cleanup();
1893}
1894
Harald Welte0e188242020-11-22 21:46:48 +01001895/* CS-PAGING on SIG-BVC for Routeing Area */
1896private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1897{
Daniel Willmannd4fb73c2020-12-07 13:57:17 +01001898 /* Only PCU index 0 has a matching BVC with the RA ID */
Harald Welte0e188242020-11-22 21:46:48 +01001899 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 +01001900 g_roi := {};
1901 /* PCU index 1 and 2 have a matching BVC with the RA ID */
1902 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
1903 g_roi := {};
1904 /* PCU index 2 has two matching BVCs with the RA ID */
1905 f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
1906 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 +01001907}
1908testcase TC_paging_cs_sig_rac() runs on test_CT {
1909 var BSSGP_ConnHdlr vc_conn;
1910 f_init();
1911
1912 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1913 vc_conn.done;
1914
1915 f_cleanup();
1916}
1917
Harald Welte7462a592020-11-23 22:07:07 +01001918/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1919private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1920{
1921 var RoutingAreaIdentification unknown_ra := {
1922 lai := {
1923 mcc_mnc := '567F99'H,
1924 lac := 33333
1925 },
1926 rac := 254
1927 };
1928 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1929}
1930testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1931 var BSSGP_ConnHdlr vc_conn;
1932 f_init();
1933
1934 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1935 vc_conn.done;
1936
1937 f_cleanup();
1938}
1939
Harald Welte0e188242020-11-22 21:46:48 +01001940/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1941private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1942{
1943 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1944}
1945testcase TC_paging_cs_sig_bvci() runs on test_CT {
1946 var BSSGP_ConnHdlr vc_conn;
1947 f_init();
1948
1949 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1950 vc_conn.done;
1951
1952 f_cleanup();
1953}
1954
Harald Welte7462a592020-11-23 22:07:07 +01001955/* CS-PAGING on SIG-BVC for unknown BVCI */
1956private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1957{
1958 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1959}
1960testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1961 var BSSGP_ConnHdlr vc_conn;
1962 f_init();
1963
1964 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1965 vc_conn.done;
1966
1967 f_cleanup();
1968}
1969
Harald Welte4f91c3b2020-12-09 12:25:51 +01001970/***********************************************************************
1971 * FLUSH-LL procedure
1972 ***********************************************************************/
1973
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001974private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1975 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1976 var integer i;
1977 for (i := 0; i < 10; i := i+1) {
1978 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1979 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1980 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1981
1982 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1983
1984 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1985 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1986 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1987
1988 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1989 }
1990 setverdict(pass);
1991}
1992testcase TC_flush_ll() runs on test_CT
1993{
1994 var BSSGP_ConnHdlr vc_conn;
1995 f_init();
1996
1997 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1998 vc_conn.done;
1999 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2000
2001 f_cleanup();
2002}
Harald Welte6dc2ac42020-11-16 09:16:17 +01002003
Harald Welte4f91c3b2020-12-09 12:25:51 +01002004/***********************************************************************
2005 * SGSN-INVOKE-TRACE procedure
2006 ***********************************************************************/
2007
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002008private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
2009runs on GlobalTest_CT {
2010[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
2011 if (ro_integer_contains(roi, pcu_idx)) {
2012 setverdict(fail, "Received multiple on same SIG BVC");
2013 }
2014 roi := roi & { pcu_idx };
2015 repeat;
2016 }
2017}
2018/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
2019testcase TC_trace() runs on GlobalTest_CT
2020{
2021 var BSSGP_ConnHdlr vc_conn;
2022 f_init();
2023 f_global_init();
2024
2025 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2026 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
2027
2028 var ro_default defaults := {};
2029 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2030 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2031 }
2032 G_SGSN[0].send(pdu_tx);
2033 f_sleep(2.0);
2034 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2035 deactivate(defaults[i]);
2036 }
2037
2038 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2039 if (not ro_integer_contains(g_roi, i)) {
2040 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
2041 }
2042 }
2043 setverdict(pass);
2044
2045 f_cleanup();
2046}
2047
Harald Welte4f91c3b2020-12-09 12:25:51 +01002048/***********************************************************************
2049 * LLC-DISCARDED procedure
2050 ***********************************************************************/
2051
Harald Weltec0351d12020-11-27 22:49:02 +01002052private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
2053 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2054
2055 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2056 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2057 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
2058
2059 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
2060
2061 setverdict(pass);
2062}
2063/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
2064testcase TC_llc_discarded() runs on test_CT
2065{
2066 var BSSGP_ConnHdlr vc_conn;
2067 f_init();
2068
2069 vc_conn := f_start_handler(refers(f_TC_llc_discarded), testcasename(), g_pcu, g_sgsn, 6);
2070 vc_conn.done;
2071 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2072
2073 f_cleanup();
2074}
2075
Harald Welte4f91c3b2020-12-09 12:25:51 +01002076/***********************************************************************
2077 * OVERLOAD procedure
2078 ***********************************************************************/
2079
Harald Weltef20af412020-11-28 16:11:11 +01002080/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
2081testcase TC_overload() runs on GlobalTest_CT
2082{
2083 f_init();
2084 f_global_init();
2085
2086 var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
2087 var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);
2088
2089 var ro_default defaults := {};
2090 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2091 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
2092 }
2093 G_SGSN[0].send(pdu_tx);
2094 f_sleep(2.0);
2095 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2096 deactivate(defaults[i]);
2097 }
2098
2099 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2100 if (not ro_integer_contains(g_roi, i)) {
2101 setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
2102 }
2103 }
2104 setverdict(pass);
2105
2106 f_cleanup();
2107}
2108
Harald Welte4f91c3b2020-12-09 12:25:51 +01002109/***********************************************************************
2110 * BVC-BLOCK / BVC-UNBLOCK procedure
2111 ***********************************************************************/
2112
Harald Welte239aa502020-11-24 23:14:20 +01002113private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2114{
2115 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2116 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2117 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2118
2119 SGSN_MGMT.clear;
2120 PCU_MGMT.clear;
2121
2122 /* block the PTP BVC from the PCU side */
2123 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
2124 /* expect state on both PCU and SGSN side to change */
2125 interleave {
2126 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
2127 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
2128 }
2129 setverdict(pass);
2130}
2131testcase TC_bvc_block_ptp() runs on test_CT
2132{
2133 f_init();
2134 f_sleep(1.0);
2135 f_block_ptp_bvc_from_pcu(0, 0);
2136 f_cleanup();
2137}
2138
2139private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2140{
2141 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2142 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2143 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2144
2145 SGSN_MGMT.clear;
2146 PCU_MGMT.clear;
2147
2148 /* block the PTP BVC from the PCU side */
2149 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
2150 /* expect state on both PCU and SGSN side to change */
2151 interleave {
2152 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
2153 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
2154 }
2155 setverdict(pass);
2156}
2157testcase TC_bvc_unblock_ptp() runs on test_CT
2158{
2159 f_init();
2160 f_sleep(1.0);
2161 f_block_ptp_bvc_from_pcu(0, 0);
2162 f_sleep(1.0);
2163 f_unblock_ptp_bvc_from_pcu(0, 0);
2164 f_cleanup();
2165}
2166
Harald Welte4f91c3b2020-12-09 12:25:51 +01002167/***********************************************************************
2168 * BVC-RESET procedure
2169 ***********************************************************************/
2170
Harald Welte60a8ec72020-11-25 17:12:53 +01002171private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
2172[] pt.receive(BssgpStatusIndication:?) { repeat; }
2173}
2174private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
2175 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
2176 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
2177 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
2178 }
2179 }
2180 return null;
2181}
2182private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
2183{
2184 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2185 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2186 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2187 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2188 var default d;
2189
2190 SGSN_MGMT.clear;
2191 PCU_MGMT.clear;
2192
2193 /* block the PTP BVC from the PCU side */
2194 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
2195 /* expect state on both PCU and SGSN side to change */
2196 d := activate(as_ignore_status(SGSN_MGMT));
2197 interleave {
2198 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
2199 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
2200 }
2201 deactivate(d);
2202 setverdict(pass);
2203}
2204/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
2205testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
2206{
2207 f_init();
2208 f_sleep(3.0);
2209 f_reset_ptp_bvc_from_pcu(0, 0);
2210 f_cleanup();
2211}
2212
Harald Welte16786e92020-11-27 19:11:56 +01002213private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
2214runs on test_CT {
2215 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
2216 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
2217 roi := roi & { bvci };
Harald Welteb2647f72020-12-07 14:36:35 +01002218 repeat;
Harald Welte16786e92020-11-27 19:11:56 +01002219 }
2220}
2221/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
2222testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
2223
2224 f_init();
2225 f_sleep(3.0);
2226
2227 /* Start BVC-RESET procedure for BVCI=0 */
2228 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
2229
2230 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
2231 var ro_default defaults := {};
2232 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2233 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2234 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2235 defaults := defaults & { d };
2236 }
2237
2238 timer T := 3.0;
2239 T.start;
2240 alt {
2241 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2242 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2243 }
2244 [] T.timeout;
2245 }
2246
2247 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2248 deactivate(defaults[i]);
2249 }
2250
2251 /* check if BVC-block was received on all expected BVC */
2252 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2253 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2254 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2255 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2256 }
2257 }
2258
2259 /* check if BVC-block was not received on any unexpected BVC is not required as
2260 * such a message would basically run into 'no matching clause' */
Daniel Willmannf2590212020-12-04 14:20:50 +01002261 setverdict(pass);
Harald Welte16786e92020-11-27 19:11:56 +01002262 f_cleanup();
2263}
2264
Harald Welte60a8ec72020-11-25 17:12:53 +01002265private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2266{
2267 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2268 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2269 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2270 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2271 var default d;
2272
2273 SGSN_MGMT.clear;
2274 PCU_MGMT.clear;
2275
2276 /* block the PTP BVC from the PCU side */
2277 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2278 /* expect state on both PCU and SGSN side to change */
2279 d := activate(as_ignore_status(PCU_MGMT));
2280 interleave {
2281 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2282 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2283 }
2284 deactivate(d);
2285 setverdict(pass);
2286}
2287/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2288testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2289{
2290 f_init();
2291 f_sleep(3.0);
2292 f_reset_ptp_bvc_from_sgsn(0, 0);
2293 f_cleanup();
2294}
2295
Harald Welte16786e92020-11-27 19:11:56 +01002296private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2297runs on test_CT {
2298 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2299 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2300 roi := roi & { nsei };
2301 }
2302}
2303/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2304testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2305
2306 f_init();
2307 f_sleep(3.0);
2308
2309 /* Start BVC-RESET procedure for BVCI=0 */
2310 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2311
2312 /* Activate altsteps: One for each PCU NSE */
2313 var ro_default defaults := {};
2314 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2315 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2316 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2317 defaults := defaults & { d };
2318 }
2319
2320 f_sleep(3.0);
2321
2322 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2323 deactivate(defaults[i]);
2324 }
2325
2326 /* check if BVC-block was received on all expected BVC */
2327 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2328 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2329 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2330 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2331 }
2332 }
2333
2334 /* check if BVC-block was not received on any unexpected BVC is not required as
2335 * such a message would basically run into 'no matching clause' */
2336
2337 f_cleanup();
2338}
2339
Harald Welte299aa482020-12-09 15:10:55 +01002340/***********************************************************************
2341 * FLOW-CONTROL-BVC procedure
2342 ***********************************************************************/
2343
2344private altstep as_g_count_sgsn(integer sgsn_idx, inout ro_integer roi,
2345 template PDU_BSSGP exp_rx, template (omit) PDU_BSSGP tx_reply)
2346runs on GlobalTest_CT {
2347 [] G_SGSN[sgsn_idx].receive(exp_rx) {
2348 roi := roi & { sgsn_idx };
2349 if (ispresent(tx_reply)) {
2350 G_SGSN[sgsn_idx].send(tx_reply);
2351 }
2352 }
2353}
2354/* Send FC-BVC from simulated PCU; expect each SGSN to receive it; expect PCU to receive ACK */
2355testcase TC_fc_bvc() runs on GlobalTest_CT
2356{
2357 f_init();
2358 f_global_init_ptp();
2359
2360 var template (value) PDU_BSSGP pdu_tx := t_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2361 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2362 var template (present) PDU_BSSGP pdu_rx := tr_BVC_FC_BVC(10240, 2000, 1024, 1000, '01'O);
2363 var template (omit) PDU_BSSGP ack_tx :=
2364 t_BVC_FC_BVC_ACK(pdu_tx.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value);
2365
2366 /* Send a FC-BVC from BSS to gbproxy, expect an ACK in response */
2367 G_PCU[0].send(pdu_tx);
2368
2369 /* Activate altsteps: One for each SGSN-side PTP BVC port */
2370 var ro_default defaults := {};
2371 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2372 var default d := activate(as_g_count_sgsn(i, g_roi, pdu_rx, ack_tx));
2373 defaults := defaults & { d };
2374 }
2375
2376 f_sleep(3.0);
2377
2378 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2379 deactivate(defaults[i]);
2380 }
2381
2382 /* check if BVC-block was received on all expected BVC */
2383 for (var integer i := 0; i < lengthof(g_sgsn); i := i+1) {
2384 if (not ro_integer_contains(g_roi, i)) {
2385 setverdict(fail, "Missing BVC-FLOW-CONTROL on SGSN index ", i);
2386 }
2387 }
2388
2389 /* Expect ACK on PCU side */
2390 G_PCU[0].receive(ack_tx);
2391
2392 setverdict(pass);
2393
2394 f_cleanup();
2395}
2396
Harald Weltecc3894b2020-12-09 16:50:12 +01002397/***********************************************************************
2398 * FLOW-CONTROL-MS procedure
2399 ***********************************************************************/
2400
2401private function f_TC_fc_ms(charstring id) runs on BSSGP_ConnHdlr {
2402 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
2403
2404 var template (value) PDU_BSSGP fc_tx := ts_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2405 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
2406 var template (present) PDU_BSSGP fc_rx := tr_BVC_FC_MS(g_pars.tlli, 100, 200, '12'O);
2407 var template (value) PDU_BSSGP ack_tx := ts_BVC_FC_MS_ACK(g_pars.tlli, '12'O);
2408
2409 f_pcu2sgsn(fc_tx, fc_rx, use_sig := false);
2410 f_sgsn2pcu(ack_tx, ack_tx, use_sig := false);
2411
2412 setverdict(pass);
2413}
2414/* Send a FLOW-CONTROL-MS from BSS side and expect it to show up on SGSN (PTP BVC) */
2415testcase TC_fc_ms() runs on test_CT
2416{
2417 var BSSGP_ConnHdlr vc_conn;
2418 f_init();
2419
2420 vc_conn := f_start_handler(refers(f_TC_fc_ms), testcasename(), g_pcu, g_sgsn, 21);
2421 vc_conn.done;
2422 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
2423
2424 f_cleanup();
2425}
2426
2427
Harald Welte299aa482020-12-09 15:10:55 +01002428
Daniel Willmann423d8f42020-09-08 18:58:22 +02002429control {
2430 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002431 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002432 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002433 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002434 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002435 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002436 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002437 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002438 execute( TC_trace() );
Harald Weltec0351d12020-11-27 22:49:02 +01002439 execute( TC_llc_discarded() );
Harald Weltef20af412020-11-28 16:11:11 +01002440 execute( TC_overload() );
Harald Welte239aa502020-11-24 23:14:20 +01002441 execute( TC_bvc_block_ptp() );
2442 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002443 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002444 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002445 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002446 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef6e59b02020-12-08 08:29:09 +01002447 if (mp_enable_bss_load_sharing) {
Harald Weltef8ef0282020-11-18 12:16:59 +01002448 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2449 execute( TC_load_sharing_dl() );
2450 }
Harald Welte0e188242020-11-22 21:46:48 +01002451
2452 /* PAGING-PS over PTP BVC */
2453 execute( TC_paging_ps_ptp_bss() );
2454 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002455 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002456 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002457 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002458 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002459 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002460
2461 /* PAGING-PS over SIG BVC */
2462 execute( TC_paging_ps_sig_bss() );
2463 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002464 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002465 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002466 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002467 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002468 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002469
2470 /* PAGING-CS over PTP BVC */
2471 execute( TC_paging_cs_ptp_bss() );
2472 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002473 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002474 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002475 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002476 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002477 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002478
2479 /* PAGING-CS over SIG BVC */
2480 execute( TC_paging_cs_sig_bss() );
2481 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002482 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002483 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002484 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002485 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002486 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002487
2488
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002489 execute( TC_flush_ll() );
Harald Welte299aa482020-12-09 15:10:55 +01002490 execute( TC_fc_bvc() );
Harald Weltecc3894b2020-12-09 16:50:12 +01002491 execute( TC_fc_ms() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002492}
2493
2494
2495}