blob: 064d1ea4e0372f2e96cb616902c940f812f37d36 [file] [log] [blame]
Daniel Willmann423d8f42020-09-08 18:58:22 +02001module GBProxy_Tests {
2
3/* Osmocom GBProxy test suite in TTCN-3
4 * (C) 2020 sysmocom - s.f.m.c. GmbH
5 * All rights reserved.
6 *
7 * Author: Daniel Willmann <dwillmann@sysmocom.de>
8
9 * Released under the terms of GNU General Public License, Version 2 or
10 * (at your option) any later version.
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15import from General_Types all;
16import from Osmocom_Types all;
17import from GSM_Types all;
18import from Native_Functions all;
19import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
23import from SCCPasp_Types all;
24import from Osmocom_Gb_Types all;
25
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from TELNETasp_PortType all;
33import from Osmocom_VTY_Functions all;
34
35import from LLC_Types all;
36import from LLC_Templates all;
37
38import from GSM_RR_Types all;
39
Harald Welte6d63f742020-11-15 19:44:04 +010040/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
41const BcdMccMnc c_mcc_mnc := '262F42'H;
42
Daniel Willmann423d8f42020-09-08 18:58:22 +020043modulepar {
44 /* IP/port on which we run our internal GSUP/HLR emulation */
Harald Welte6d63f742020-11-15 19:44:04 +010045 NSConfigurations mp_nsconfig_sgsn := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020046 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020047 nsei := 101,
48 role_sgsn := true,
Harald Welte90f19742020-11-06 19:34:40 +010049 handle_sns := false,
50 nsvc := {
51 {
52 provider := {
53 ip := {
54 address_family := AF_INET,
55 local_udp_port := 7777,
56 local_ip := "127.0.0.1",
57 remote_udp_port := 23000,
58 remote_ip := "127.0.0.1"
59 }
60 },
61 nsvci := 101
62 }
63 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020064 }
65 };
Harald Welte6d63f742020-11-15 19:44:04 +010066 NSConfigurations mp_nsconfig_pcu := {
Daniel Willmann423d8f42020-09-08 18:58:22 +020067 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020068 nsei := 96,
69 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010070 handle_sns := false,
71 nsvc := {
72 {
73 provider := {
74 ip := {
75 address_family := AF_INET,
76 local_udp_port := 21010,
77 local_ip := "127.0.0.1",
78 remote_udp_port := 23000,
79 remote_ip := "127.0.0.1"
80 }
81 },
82 nsvci := 97
83 }
84 }
Daniel Willmann423d8f42020-09-08 18:58:22 +020085 },
86 {
Daniel Willmann423d8f42020-09-08 18:58:22 +020087 nsei := 97,
88 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010089 handle_sns := false,
90 nsvc := {
91 {
92 provider := {
93 ip := {
94 address_family := AF_INET,
95 local_udp_port := 21011,
96 local_ip := "127.0.0.1",
97 remote_udp_port := 23000,
98 remote_ip := "127.0.0.1"
99 }
100 },
101 nsvci := 98
102 }
103 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200104 },
105 {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200106 nsei := 98,
107 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100108 handle_sns := false,
109 nsvc := {
110 {
111 provider := {
112 ip := {
113 address_family := AF_INET,
114 local_udp_port := 21012,
115 local_ip := "127.0.0.1",
116 remote_udp_port := 23000,
117 remote_ip := "127.0.0.1"
118 }
119 },
120 nsvci := 99
121 }
122 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200123 }
124 };
Harald Welte6d63f742020-11-15 19:44:04 +0100125 BssgpConfigs mp_gbconfigs := {
126 {
127 nsei := 96,
128 sgsn_role := false,
129 bvc := {
130 {
131 bvci := 196,
132 cell_id := {
133 ra_id := {
134 lai := {
135 mcc_mnc := c_mcc_mnc,
136 lac := 13135
137 },
138 rac := 0
139 },
140 cell_id := 20960
141 },
142 depth := BSSGP_DECODE_DEPTH_BSSGP,
143 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
144 }
145 }
146 }, {
147 nsei := 97,
148 sgsn_role := false,
149 bvc := {
150 {
151 bvci := 210,
152 cell_id := {
153 ra_id := {
154 lai := {
155 mcc_mnc := c_mcc_mnc,
Harald Welte0e188242020-11-22 21:46:48 +0100156 lac := 13135
Harald Welte6d63f742020-11-15 19:44:04 +0100157 },
Harald Welte0e188242020-11-22 21:46:48 +0100158 rac := 1
Harald Welte6d63f742020-11-15 19:44:04 +0100159 },
160 cell_id := 20961
161 },
162 depth := BSSGP_DECODE_DEPTH_BSSGP,
163 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
164 }
165 }
166 }, {
167 nsei := 98,
168 sgsn_role := false,
169 bvc := {
170 {
171 bvci := 220,
172 cell_id := {
173 ra_id := {
174 lai := {
175 mcc_mnc := c_mcc_mnc,
176 lac := 13300
177 },
178 rac := 0
179 },
180 cell_id := 20962
181 },
182 depth := BSSGP_DECODE_DEPTH_BSSGP,
183 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
184 }
185 }
186 }
187 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200188};
189
Daniel Willmann423d8f42020-09-08 18:58:22 +0200190type record GbInstance {
191 NS_CT vc_NS,
192 BSSGP_CT vc_BSSGP,
Harald Welte67dc8c22020-11-17 18:32:29 +0100193 BSSGP_BVC_CTs vc_BSSGP_BVC,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200194 BssgpConfig cfg
195};
Harald Welte67dc8c22020-11-17 18:32:29 +0100196type record of BSSGP_BVC_CT BSSGP_BVC_CTs
Daniel Willmann423d8f42020-09-08 18:58:22 +0200197
198const integer NUM_PCU := 3;
Harald Welte6d63f742020-11-15 19:44:04 +0100199type record of GbInstance GbInstances;
200type record of BssgpConfig BssgpConfigs;
201type record of NSConfiguration NSConfigurations;
202type record of BssgpCellId BssgpCellIds;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200203
204const integer NUM_SGSN := 1;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200205
206type component test_CT {
Harald Welte6d63f742020-11-15 19:44:04 +0100207 var GbInstances g_pcu;
208 var GbInstances g_sgsn;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200209
210 port BSSGP_CT_PROC_PT PROC;
211
Harald Weltefbae83f2020-11-15 23:25:55 +0100212 port BSSGP_BVC_MGMT_PT SGSN_MGMT;
213 port BSSGP_BVC_MGMT_PT PCU_MGMT;
214
Daniel Willmann423d8f42020-09-08 18:58:22 +0200215 port TELNETasp_PT GBPVTY;
216
217 var boolean g_initialized := false;
218 var boolean g_use_echo := false;
219};
220
221type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100222 /* array of per-BVC ports on the PCU side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200223 port BSSGP_PT PCU[NUM_PCU];
224 port BSSGP_PT PCU_SIG[NUM_PCU];
225 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100226 /* component reference to the component to which we're currently connected */
227 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100228 /* BSSGP BVC configuration of the component to which we're currently connected */
229 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100230
231 /* array of per-BVC ports on the SGSN side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200232 port BSSGP_PT SGSN[NUM_SGSN];
233 port BSSGP_PT SGSN_SIG[NUM_SGSN];
234 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100235 /* component reference to the component to which we're currently connected */
236 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200237
238 var BSSGP_ConnHdlrPars g_pars;
239 timer g_Tguard;
240 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100241
242 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200243}
244
245type record SGSN_ConnHdlrNetworkPars {
246 boolean expect_ptmsi,
247 boolean expect_auth,
248 boolean expect_ciph
249};
250
251type record BSSGP_ConnHdlrPars {
252 /* IMEI of the simulated ME */
253 hexstring imei,
254 /* IMSI of the simulated MS */
255 hexstring imsi,
256 /* MSISDN of the simulated MS (probably unused) */
257 hexstring msisdn,
258 /* P-TMSI allocated to the simulated MS */
259 OCT4 p_tmsi optional,
260 OCT3 p_tmsi_sig optional,
261 /* TLLI of the simulated MS */
262 OCT4 tlli,
263 OCT4 tlli_old optional,
264 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100265 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100266 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200267 float t_guard
268};
269
270private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
271 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
272 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
273
274 var RoutingAreaIdentificationV ret := {
275 mccDigit1 := mcc_mnc[0],
276 mccDigit2 := mcc_mnc[1],
277 mccDigit3 := mcc_mnc[2],
278 mncDigit3 := mcc_mnc[3],
279 mncDigit1 := mcc_mnc[4],
280 mncDigit2 := mcc_mnc[5],
281 lac := int2oct(cell_id.ra_id.lai.lac, 16),
282 rac := int2oct(cell_id.ra_id.rac, 8)
283 }
284 return ret;
285};
286
287private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100288 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
289 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
290 gb.vc_NS := NS_CT.create(ns_id);
291 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200292 /* connect lower end of BSSGP emulation with NS upper port */
293 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
294
Harald Welteb419d0e2020-11-16 16:45:05 +0100295 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
296 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200297
298 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
299 connect(self:PROC, gb.vc_BSSGP:PROC);
300 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
301 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100302 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200303 }
304}
305
306private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100307 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
308 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
309 gb.vc_NS := NS_CT.create(ns_id);
310 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200311 /* connect lower end of BSSGP emulation with NS upper port */
312 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
313
Harald Welteb419d0e2020-11-16 16:45:05 +0100314 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
315 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200316
317 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
318 connect(self:PROC, gb.vc_BSSGP:PROC);
319 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
320 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100321 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200322 }
323}
324
325
326private function f_init_vty() runs on test_CT {
327 map(self:GBPVTY, system:GBPVTY);
328 f_vty_set_prompts(GBPVTY);
329 f_vty_transceive(GBPVTY, "enable");
330}
331
Harald Weltefbae83f2020-11-15 23:25:55 +0100332type record of integer ro_integer;
333
334private function ro_integer_contains(ro_integer r, integer x) return boolean {
335 for (var integer j := 0; j < lengthof(r); j := j+1) {
336 if (r[j] == x) {
337 return true;
338 }
339 }
340 return false;
341}
342
Harald Welte6d63f742020-11-15 19:44:04 +0100343function f_init() runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100344 var ro_integer bvci_unblocked := {};
345 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200346 var integer i;
347
348 if (g_initialized == true) {
349 return;
350 }
351 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200352
353 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100354 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200355 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100356 bvc := { }
357 }
358 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
359 g_pcu[i].cfg := mp_gbconfigs[i];
360 /* concatenate all the PCU-side BVCs for the SGSN side */
361 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & mp_gbconfigs[i].bvc;
362 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200363
364 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100365 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100366 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Harald Welteea1ba592020-11-17 18:05:13 +0100367 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100368 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200369 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100370 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100371 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100372 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100373
374 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100375 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100376 T.start;
377 alt {
378 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
379 bvci_unblocked := bvci_unblocked & { bsi.bvci };
380 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
381 repeat;
382 }
383 }
384 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
385 repeat;
386 }
Harald Welte3c905152020-11-26 20:56:09 +0100387 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
388 repeat;
389 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100390 [] SGSN_MGMT.receive {
391 setverdict(fail, "Received unexpected message on SGSN_MGMT");
392 mtc.stop;
393 }
394
395 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
396 repeat;
397 }
398 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
399 repeat;
400 }
401 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
402 repeat;
403 }
404 [] PCU_MGMT.receive {
405 setverdict(fail, "Received unexpected message on PCU_MGMT");
406 mtc.stop;
407 }
408
409 [] T.timeout {
410 setverdict(fail, "Timeout waiting for unblock of all BVCs");
411 mtc.stop;
412 }
413 }
414
415 /* iterate over list and check all BVCI */
416 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
417 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
418 if (not ro_integer_contains(bvci_unblocked, bvci)) {
419 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
420 mtc.stop;
421 }
422 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200423}
424
425function f_cleanup() runs on test_CT {
426 self.stop;
427}
428
429type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
430
431/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100432function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200433 float t_guard := 30.0)
434runs on test_CT return BSSGP_ConnHdlr {
435 var BSSGP_ConnHdlr vc_conn;
436
437 var BSSGP_ConnHdlrPars pars := {
438 imei := f_gen_imei(imsi_suffix),
439 imsi := f_gen_imsi(imsi_suffix),
440 msisdn := f_gen_msisdn(imsi_suffix),
441 p_tmsi := omit,
442 p_tmsi_sig := omit,
443 tlli := f_gprs_tlli_random(),
444 tlli_old := omit,
445 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100446 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100447 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200448 t_guard := t_guard
449 };
450
451 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452
453 vc_conn.start(f_handler_init(fn, id, pars));
454 return vc_conn;
455}
456
Harald Welte3dd21b32020-11-17 19:21:00 +0100457/* 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 +0100458private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
459runs on BSSGP_ConnHdlr {
460 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100461 if (PCU[port_idx].checkstate("Connected")) {
462 /* unregister + disconnect from old BVC */
463 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
464 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
465 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
466 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
467 }
468 /* connect to new BVC and register us */
469 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
470 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
471 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
472 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
473 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100474 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100475}
476
477/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
478private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
479 if (SGSN[port_idx].checkstate("Connected")) {
480 /* unregister + disconnect from old BVC */
481 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
482 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
483 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
484 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
485 }
486 /* connect to new BVC and register us */
487 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
488 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
489 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
490 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
491 sgsn_ct[port_idx] := bvc_ct;
492}
493
Daniel Willmann423d8f42020-09-08 18:58:22 +0200494private altstep as_Tguard() runs on BSSGP_ConnHdlr {
495 [] g_Tguard.timeout {
496 setverdict(fail, "Tguard timeout");
497 mtc.stop;
498 }
499}
500
501/* first function called in every ConnHdlr */
502private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
503runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100504 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200505 /* do some common stuff like setting up g_pars */
506 g_pars := pars;
507
508 llc := f_llc_create(false);
509
Harald Welte3dd21b32020-11-17 19:21:00 +0100510 /* default connections on PCU side: First BVC of each NSE/PCU */
511 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100512 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100513 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100514
515 /* default connections on SGSN side: First BVC of each NSE/SGSN */
516 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
517 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100518 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200519
520 g_Tguard.start(pars.t_guard);
521 activate(as_Tguard());
522
523 /* call the user-supplied test case function */
524 fn.apply(id);
525}
526
Harald Welte1e834f32020-11-15 20:02:59 +0100527private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
528runs on BSSGP_ConnHdlr {
529 PT.call(BSSGP_register_client:{imsi, tlli}) {
530 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
531 }
532}
533
534private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
535runs on BSSGP_ConnHdlr {
536 PT.call(BSSGP_unregister_client:{imsi}) {
537 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
538 }
539}
540
Harald Welte22ef5d92020-11-16 13:35:14 +0100541/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
542friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100543 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100544 var PDU_BSSGP rx;
545 timer T := 1.0;
546
Daniel Willmann4798fd72020-11-24 16:23:29 +0100547 if (use_sig) {
548 PCU_SIG[pcu_idx].send(tx);
549 } else {
550 PCU[pcu_idx].send(tx);
551 }
552
Harald Welte22ef5d92020-11-16 13:35:14 +0100553 T.start;
554 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100555 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
556 setverdict(pass);
557 }
558 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100559 setverdict(pass);
560 }
561 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
562 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
563 mtc.stop;
564 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100565 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
566 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
567 mtc.stop;
568 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100569 [] T.timeout {
570 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
571 mtc.stop;
572 }
573 }
574}
575
576/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
577friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100578 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100579 var PDU_BSSGP rx;
580 timer T := 1.0;
581
Daniel Willmann4798fd72020-11-24 16:23:29 +0100582 if (use_sig) {
583 SGSN_SIG[sgsn_idx].send(tx);
584 } else {
585 SGSN[sgsn_idx].send(tx);
586 }
587
Harald Welte22ef5d92020-11-16 13:35:14 +0100588 T.start;
589 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100590 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
591 setverdict(pass);
592 }
593 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100594 setverdict(pass);
595 }
596 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
597 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
598 mtc.stop;
599 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100600 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
601 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
602 mtc.stop;
603 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100604 [] T.timeout {
605 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
606 mtc.stop;
607 }
608 }
609}
Harald Welte1e834f32020-11-15 20:02:59 +0100610
Harald Welte3807ed12020-11-24 19:05:22 +0100611/***********************************************************************
612 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
613 ***********************************************************************/
614
615type component GlobalTest_CT extends test_CT {
616 port BSSGP_PT G_PCU[NUM_PCU];
617 port BSSGP_PT G_SGSN[NUM_SGSN];
618};
619
620private function f_global_init() runs on GlobalTest_CT {
621 var integer i;
622 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
623 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
624 }
625 for (i := 0; i < lengthof(g_pcu); i := i+1) {
626 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
627 }
628}
629
630/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
631friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
632 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
633 var PDU_BSSGP rx;
634 timer T := 1.0;
635
636 G_PCU[pcu_idx].send(tx);
637 T.start;
638 alt {
639 [] G_SGSN[sgsn_idx].receive(exp_rx) {
640 setverdict(pass);
641 }
642 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
643 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
644 mtc.stop;
645 }
646 [] T.timeout {
647 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
648 mtc.stop;
649 }
650 }
651}
652
653/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
654friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
655 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
656 var PDU_BSSGP rx;
657 timer T := 1.0;
658
659 G_SGSN[sgsn_idx].send(tx);
660 T.start;
661 alt {
662 [] G_PCU[pcu_idx].receive(exp_rx) {
663 setverdict(pass);
664 }
665 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
666 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
667 mtc.stop;
668 }
669 [] T.timeout {
670 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
671 mtc.stop;
672 }
673 }
674}
675
676
Daniel Willmann423d8f42020-09-08 18:58:22 +0200677/* TODO:
678 * Detach without Attach
679 * SM procedures without attach / RAU
680 * ATTACH / RAU
681 ** with / without authentication
682 ** with / without P-TMSI allocation
683 * re-transmissions of LLC frames
684 * PDP Context activation
685 ** with different GGSN config in SGSN VTY
686 ** with different PDP context type (v4/v6/v46)
687 ** timeout from GGSN
688 ** multiple / secondary PDP context
689 */
690
691private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
692 f_sleep(5.0);
693 setverdict(pass);
694}
695
696testcase TC_BVC_bringup() runs on test_CT {
697 var BSSGP_ConnHdlr vc_conn;
698 f_init();
699
700 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
701 vc_conn.done;
702
703 f_cleanup();
704}
705
706friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100707 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200708 timer T := 5.0;
709 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100710 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200711 T.start;
712 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100713 [] 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 +0200714 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
715 }
Harald Welte16357a92020-11-17 18:20:00 +0100716 [] 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 +0200717 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
718 mtc.stop;
719 }
720 [] T.timeout {
721 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
722 mtc.stop;
723 }
724 }
725 return '00'O;
726}
727
728friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100729 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200730 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100731 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 +0200732 T.start;
733 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100734 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
735 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200736 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
737 mtc.stop;
738 }
739 [] T.timeout {
740 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
741 mtc.stop;
742 }
743 }
744}
745
746
Harald Welte92686012020-11-15 21:45:49 +0100747/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
748private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100749 var integer ran_idx := 0;
750 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100751 var integer i;
752
753 for (i := 0; i < 1024; i := i+1) {
754 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100755 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 +0100756 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100757 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 +0100758
Harald Welte22ef5d92020-11-16 13:35:14 +0100759 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100760 }
761 setverdict(pass);
762}
763
764testcase TC_ul_unitdata() runs on test_CT
765{
766 var BSSGP_ConnHdlr vc_conn;
767 f_init();
768
769 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
770 vc_conn.done;
771 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
772
773 f_cleanup();
774}
775
Harald Welte78d8db92020-11-15 23:27:27 +0100776/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
777private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
778 var integer i;
779
780 for (i := 0; i < 1024; i := i+1) {
781 var octetstring payload := f_rnd_octstring(i);
782 var template (value) PDU_BSSGP pdu_tx :=
783 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
784 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
785 var template (present) PDU_BSSGP pdu_rx :=
786 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
787
Harald Welte22ef5d92020-11-16 13:35:14 +0100788 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100789 }
790 setverdict(pass);
791}
792
793testcase TC_dl_unitdata() runs on test_CT
794{
795 var BSSGP_ConnHdlr vc_conn;
796 f_init();
797
798 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
799 vc_conn.done;
800 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
801
802 f_cleanup();
803}
Harald Welte92686012020-11-15 21:45:49 +0100804
Harald Welte6dc2ac42020-11-16 09:16:17 +0100805private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
806 var integer i;
807
808 for (i := 0; i < 10; i := i+1) {
809 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
810 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
811 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
812
Harald Welte22ef5d92020-11-16 13:35:14 +0100813 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100814 }
815 setverdict(pass);
816}
817testcase TC_ra_capability() runs on test_CT
818{
819 var BSSGP_ConnHdlr vc_conn;
820 f_init();
821
822 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
823 vc_conn.done;
824 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
825
826 f_cleanup();
827}
828
Daniel Willmannace3ece2020-11-16 19:53:26 +0100829private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
830 var integer i;
831 var OCT1 tag;
832 for (i := 0; i < 10; i := i+1) {
833 tag := int2oct(23 + i, 1);
834 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
835 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
836 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
837
838 f_pcu2sgsn(pdu_tx, pdu_rx);
839
840 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
841 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
842 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
843
844 f_sgsn2pcu(pdu_tx, pdu_rx);
845 }
846 setverdict(pass);
847}
848testcase TC_ra_capability_upd() runs on test_CT
849{
850 var BSSGP_ConnHdlr vc_conn;
851 f_init();
852
Daniel Willmann54833f22020-11-19 15:43:52 +0100853 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100854 vc_conn.done;
855 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
856
857 f_cleanup();
858}
859
Daniel Willmann165d6612020-11-19 14:27:29 +0100860private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
861 var integer i;
862 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
863 for (i := 0; i < 10; i := i+1) {
864 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
865 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
866 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
867
868 f_pcu2sgsn(pdu_tx, pdu_rx);
869 }
870 setverdict(pass);
871}
872testcase TC_radio_status() runs on test_CT
873{
874 var BSSGP_ConnHdlr vc_conn;
875 f_init();
876
Daniel Willmann54833f22020-11-19 15:43:52 +0100877 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100878 vc_conn.done;
879 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
880
881 f_cleanup();
882}
883
Harald Welte3807ed12020-11-24 19:05:22 +0100884private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100885 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100886
Daniel Willmannfa67f492020-11-19 15:48:05 +0100887 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100888 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100889 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100890 var OCT4 tlli := f_gprs_tlli_random();
891 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100892 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100893 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100894
Harald Welte3807ed12020-11-24 19:05:22 +0100895 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100896
Harald Welte3807ed12020-11-24 19:05:22 +0100897 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100898 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100899 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100900
Harald Welte3807ed12020-11-24 19:05:22 +0100901 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100902
903 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100904 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100905 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100906 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100907
Harald Welte3807ed12020-11-24 19:05:22 +0100908 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100909 }
910 setverdict(pass);
911}
Harald Welte3807ed12020-11-24 19:05:22 +0100912testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100913{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100914 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100915 f_global_init();
916 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +0100917 f_cleanup();
918}
Harald Welte6dc2ac42020-11-16 09:16:17 +0100919
Harald Welte3807ed12020-11-24 19:05:22 +0100920private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +0100921 var integer i;
922
923 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100924 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +0100925 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100926 var OCT4 tlli := f_gprs_tlli_random();
927 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100928 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100929 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100930
Harald Welte3807ed12020-11-24 19:05:22 +0100931 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100932
Harald Welte3807ed12020-11-24 19:05:22 +0100933 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100934 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100935 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100936
Harald Welte3807ed12020-11-24 19:05:22 +0100937 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100938
939 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100940 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100941 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100942 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100943
Harald Welte3807ed12020-11-24 19:05:22 +0100944 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100945 }
946 setverdict(pass);
947}
Harald Welte3807ed12020-11-24 19:05:22 +0100948testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +0100949{
Daniel Willmann087a33d2020-11-19 15:58:43 +0100950 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100951 f_global_init();
952 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +0100953 f_cleanup();
954}
955
Harald Weltef8ef0282020-11-18 12:16:59 +0100956/* test the load-sharing between multiple NS-VC on the BSS side */
957private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
958 var integer i;
959
960 for (i := 0; i < 10; i := i+1) {
961 var octetstring payload := f_rnd_octstring(i);
962 var template (value) PDU_BSSGP pdu_tx :=
963 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
964 SGSN[0].send(pdu_tx);
965 }
966 setverdict(pass);
967}
968testcase TC_load_sharing_dl() runs on test_CT_NS
969{
970 const integer num_ue := 10;
971 var BSSGP_ConnHdlr vc_conn[num_ue];
972 f_init();
973
974 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
975 * side so we get the raw NsUnitdataIndication and hence observe different
976 * NSVCI */
977 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
978 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
979
980 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
981 * of the NS-VC is ALIVE/UNBLOCKED */
982 f_sleep(3.0);
983
984 /* start parallel components generating DL-UNITDATA from the SGSN side */
985 for (var integer i:= 0; i < num_ue; i := i+1) {
986 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
987 }
988
989 /* now start counting all the messages that were queued before */
990 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
991 var ro_integer rx_count := { 0, 0, 0, 0 };
992 timer T := 2.0;
993 T.start;
994 alt {
995 [] as_NsUdiCount(0, rx_count);
996 [] as_NsUdiCount(1, rx_count);
997 [] as_NsUdiCount(2, rx_count);
998 [] as_NsUdiCount(3, rx_count);
999 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1000 [] NS.receive(NsStatusIndication:?) { repeat; }
1001 [] NS.receive {
1002 setverdict(fail, "Rx unexpected NS");
1003 mtc.stop;
1004 }
1005 [] T.timeout {
1006 }
1007 }
1008 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1009 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1010 if (rx_count[i] == 0) {
1011 setverdict(fail, "Data not shared over all NSVC");
1012 }
1013 }
1014 setverdict(pass);
1015}
1016private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1017 var NsUnitdataIndication udi;
1018 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1019 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1020 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1021 repeat;
1022 }
1023}
1024type component test_CT_NS extends test_CT {
1025 port NS_PT NS;
1026};
1027
1028
Harald Welte0e188242020-11-22 21:46:48 +01001029/***********************************************************************
1030 * PAGING PS procedure
1031 ***********************************************************************/
1032
1033private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1034 boolean use_sig := false)
1035runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1036 var template (value) PDU_BSSGP pdu_tx;
1037 var template (present) PDU_BSSGP pdu_rx;
1038 /* we always specify '0' as BVCI in the templates below, as we override it with
1039 * 'p4' later anyway */
1040 pdu_rx := tr_BSSGP_PS_PAGING(0);
1041 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1042 if (ispresent(g_pars.p_tmsi)) {
1043 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1044 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1045 } else {
1046 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1047 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1048 }
1049 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1050 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1051 if (use_sig == false) {
1052 SGSN[sgsn_idx].send(pdu_tx);
1053 } else {
1054 SGSN_SIG[sgsn_idx].send(pdu_tx);
1055 }
1056 return pdu_rx;
1057}
1058
1059/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1060 * specified PCU index */
1061private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1062 boolean use_sig := false,integer pcu_idx := 0)
1063runs on BSSGP_ConnHdlr {
1064 var template (present) PDU_BSSGP exp_rx;
1065 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1066 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1067 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1068 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1069 timer T := 2.0;
1070 T.start;
1071 alt {
1072 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1073 setverdict(pass);
1074 repeat;
1075 }
1076 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1077 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1078 }
1079 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1080 setverdict(pass);
1081 repeat;
1082 }
1083 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1084 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1085 }
1086 [] any from PCU.receive(exp_rx) {
1087 setverdict(fail, "Paging received on unexpected BVC");
1088 }
1089 [] any from PCU_SIG.receive(exp_rx) {
1090 setverdict(fail, "Paging received on unexpected BVC");
1091 }
1092 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1093 setverdict(fail, "Different Paging than expected received PTP BVC");
1094 }
1095 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1096 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1097 }
1098 [] T.timeout;
1099 }
1100}
1101
Harald Welte7462a592020-11-23 22:07:07 +01001102/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1103private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1104 boolean use_sig := false)
1105runs on BSSGP_ConnHdlr {
1106 var template (present) PDU_BSSGP exp_rx;
1107 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1108 /* Expect paging to propagate to no BSS */
1109 timer T := 2.0;
1110 T.start;
1111 alt {
1112 [] any from PCU.receive(exp_rx) {
1113 setverdict(fail, "Paging received on unexpected BVC");
1114 }
1115 [] any from PCU_SIG.receive(exp_rx) {
1116 setverdict(fail, "Paging received on unexpected BVC");
1117 }
1118 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1119 setverdict(fail, "Different Paging received on PTP BVC");
1120 }
1121 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1122 setverdict(fail, "Different Paging received on SIGNALING BVC");
1123 }
1124 [] T.timeout {
1125 setverdict(pass);
1126 }
1127 }
1128}
1129
Harald Welte0e188242020-11-22 21:46:48 +01001130private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1131{
1132 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1133 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1134 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1135}
1136testcase TC_paging_ps_ptp_bss() runs on test_CT {
1137 var BSSGP_ConnHdlr vc_conn;
1138 f_init();
1139
1140 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1141 vc_conn.done;
1142
1143 f_cleanup();
1144}
1145
1146/* PS-PAGING on PTP-BVC for Location Area */
1147private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1148{
1149 var template (present) PDU_BSSGP exp_rx;
1150 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1151 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1152 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1153}
1154testcase TC_paging_ps_ptp_lac() runs on test_CT {
1155 var BSSGP_ConnHdlr vc_conn;
1156 f_init();
1157
1158 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1159 vc_conn.done;
1160
1161 f_cleanup();
1162}
1163
Harald Welte7462a592020-11-23 22:07:07 +01001164/* PS-PAGING on PTP-BVC for unknown Location Area */
1165private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1166{
1167 var GSM_Types.LocationAreaIdentification unknown_la := {
1168 mcc_mnc := '567F99'H,
1169 lac := 33333
1170 };
1171 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1172 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1173}
1174testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1175 var BSSGP_ConnHdlr vc_conn;
1176 f_init();
1177
1178 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1179 vc_conn.done;
1180
1181 f_cleanup();
1182}
1183
Harald Welte0e188242020-11-22 21:46:48 +01001184/* PS-PAGING on PTP-BVC for Routeing Area */
1185private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1186{
1187 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1188 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1189 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1190}
1191testcase TC_paging_ps_ptp_rac() runs on test_CT {
1192 var BSSGP_ConnHdlr vc_conn;
1193 f_init();
1194
1195 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1196 vc_conn.done;
1197
1198 f_cleanup();
1199}
1200
Harald Welte7462a592020-11-23 22:07:07 +01001201/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1202private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1203{
1204 var RoutingAreaIdentification unknown_ra := {
1205 lai := {
1206 mcc_mnc := '567F99'H,
1207 lac := 33333
1208 },
1209 rac := 254
1210 };
1211 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1212 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1213}
1214testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1215 var BSSGP_ConnHdlr vc_conn;
1216 f_init();
1217
1218 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1219 vc_conn.done;
1220
1221 f_cleanup();
1222}
1223
Harald Welte0e188242020-11-22 21:46:48 +01001224/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1225private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1226{
1227 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1228 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1229}
1230testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1231 var BSSGP_ConnHdlr vc_conn;
1232 f_init();
1233
1234 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1235 vc_conn.done;
1236
1237 f_cleanup();
1238}
1239
Harald Welte7462a592020-11-23 22:07:07 +01001240/* PS-PAGING on PTP-BVC for unknown BVCI */
1241private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1242{
1243 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1244 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1245}
1246testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1247 var BSSGP_ConnHdlr vc_conn;
1248 f_init();
1249
1250 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1251 vc_conn.done;
1252
1253 f_cleanup();
1254}
1255
Harald Welte0e188242020-11-22 21:46:48 +01001256/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1257private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1258runs on BSSGP_ConnHdlr {
1259[] PCU_SIG[pcu_idx].receive(exp_rx) {
1260 if (ro_integer_contains(roi, pcu_idx)) {
1261 setverdict(fail, "Received multiple paging on same SIG BVC");
1262 }
1263 roi := roi & { pcu_idx };
1264 repeat;
1265 }
1266[] PCU[pcu_idx].receive(exp_rx) {
1267 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1268 }
1269[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1270 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1271 }
1272[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1273 setverdict(fail, "Different Paging than expected received PTP BVC");
1274 }
1275}
1276
1277type record of default ro_default;
1278
1279/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1280private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1281 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1282{
1283 var template (present) PDU_BSSGP exp_rx;
1284 exp_rx := f_send_paging_ps(p4, 0, true);
1285
1286 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1287 var ro_default defaults := {};
1288 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1289 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1290 defaults := defaults & { d };
1291 }
1292 f_sleep(2.0);
1293 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1294 deactivate(defaults[i]);
1295 }
1296 log("Paging received on PCU ", g_roi);
1297
1298 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1299 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1300 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1301 if (exp_on_i and not rx_on_i) {
1302 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1303 }
1304 if (not exp_on_i and rx_on_i) {
1305 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1306 }
1307 }
1308 setverdict(pass);
1309}
1310
1311/* PS-PAGING on SIG-BVC for BSS Area */
1312private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1313{
1314 /* we expect the paging to arrive on all three NSE */
1315 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1316}
1317testcase TC_paging_ps_sig_bss() runs on test_CT {
1318 var BSSGP_ConnHdlr vc_conn;
1319 f_init();
1320
1321 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1322 vc_conn.done;
1323
1324 f_cleanup();
1325}
1326
1327/* PS-PAGING on SIG-BVC for Location Area */
1328private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1329{
1330 /* Both PCU index 0 and 1 have a BVC within the LAC */
1331 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1332}
1333testcase TC_paging_ps_sig_lac() runs on test_CT {
1334 var BSSGP_ConnHdlr vc_conn;
1335 f_init();
1336
1337 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1338 vc_conn.done;
1339
1340 f_cleanup();
1341}
1342
Harald Welte7462a592020-11-23 22:07:07 +01001343/* PS-PAGING on SIG-BVC for unknown Location Area */
1344private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1345{
1346 var GSM_Types.LocationAreaIdentification unknown_la := {
1347 mcc_mnc := '567F99'H,
1348 lac := 33333
1349 };
1350 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1351}
1352testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1353 var BSSGP_ConnHdlr vc_conn;
1354 f_init();
1355
1356 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1357 vc_conn.done;
1358
1359 f_cleanup();
1360}
1361
Harald Welte0e188242020-11-22 21:46:48 +01001362/* PS-PAGING on SIG-BVC for Routeing Area */
1363private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1364{
1365 /* Only PCU index 0 has a matching BVC within the LAC */
1366 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1367}
1368testcase TC_paging_ps_sig_rac() runs on test_CT {
1369 var BSSGP_ConnHdlr vc_conn;
1370 f_init();
1371
1372 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1373 vc_conn.done;
1374
1375 f_cleanup();
1376}
1377
Harald Welte7462a592020-11-23 22:07:07 +01001378/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1379private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1380{
1381 var RoutingAreaIdentification unknown_ra := {
1382 lai := {
1383 mcc_mnc := '567F99'H,
1384 lac := 33333
1385 },
1386 rac := 254
1387 };
1388 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1389}
1390testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1391 var BSSGP_ConnHdlr vc_conn;
1392 f_init();
1393
1394 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1395 vc_conn.done;
1396
1397 f_cleanup();
1398}
1399
Harald Welte0e188242020-11-22 21:46:48 +01001400/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1401private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1402{
1403 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1404}
1405testcase TC_paging_ps_sig_bvci() runs on test_CT {
1406 var BSSGP_ConnHdlr vc_conn;
1407 f_init();
1408
1409 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1410 vc_conn.done;
1411
1412 f_cleanup();
1413}
1414
Harald Welte7462a592020-11-23 22:07:07 +01001415/* PS-PAGING on SIG-BVC for unknown BVCI */
1416private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1417{
1418 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1419}
1420testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1421 var BSSGP_ConnHdlr vc_conn;
1422 f_init();
1423
1424 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1425 vc_conn.done;
1426
1427 f_cleanup();
1428}
1429
1430
Harald Welte0e188242020-11-22 21:46:48 +01001431
1432/***********************************************************************
1433 * PAGING CS procedure
1434 ***********************************************************************/
1435
1436private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1437 boolean use_sig := false)
1438runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1439 var template (value) PDU_BSSGP pdu_tx;
1440 var template (present) PDU_BSSGP pdu_rx;
1441 /* we always specify '0' as BVCI in the templates below, as we override it with
1442 * 'p4' later anyway */
1443 pdu_rx := tr_BSSGP_CS_PAGING(0);
1444 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1445 if (ispresent(g_pars.p_tmsi)) {
1446 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1447 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1448 } else {
1449 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1450 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1451 }
1452 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1453 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1454 if (use_sig == false) {
1455 SGSN[sgsn_idx].send(pdu_tx);
1456 } else {
1457 SGSN_SIG[sgsn_idx].send(pdu_tx);
1458 }
1459 return pdu_rx;
1460}
1461
1462/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1463 * specified PCU index */
1464private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1465 boolean use_sig := false,integer pcu_idx := 0)
1466runs on BSSGP_ConnHdlr {
1467 var template (present) PDU_BSSGP exp_rx;
1468 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1469 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1470 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1471 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1472 timer T := 2.0;
1473 T.start;
1474 alt {
1475 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1476 setverdict(pass);
1477 repeat;
1478 }
1479 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1480 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1481 }
1482 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1483 setverdict(pass);
1484 repeat;
1485 }
1486 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1487 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1488 }
1489 [] any from PCU.receive(exp_rx) {
1490 setverdict(fail, "Paging received on unexpected BVC");
1491 }
1492 [] any from PCU_SIG.receive(exp_rx) {
1493 setverdict(fail, "Paging received on unexpected BVC");
1494 }
1495 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1496 setverdict(fail, "Different Paging than expected received PTP BVC");
1497 }
1498 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1499 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1500 }
1501 [] T.timeout;
1502 }
1503}
1504
Harald Welte7462a592020-11-23 22:07:07 +01001505/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1506private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1507 boolean use_sig := false)
1508runs on BSSGP_ConnHdlr {
1509 var template (present) PDU_BSSGP exp_rx;
1510 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1511 /* Expect paging to propagate to no BSS */
1512 timer T := 2.0;
1513 T.start;
1514 alt {
1515 [] any from PCU.receive(exp_rx) {
1516 setverdict(fail, "Paging received on unexpected BVC");
1517 }
1518 [] any from PCU_SIG.receive(exp_rx) {
1519 setverdict(fail, "Paging received on unexpected BVC");
1520 }
1521 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1522 setverdict(fail, "Different Paging received on PTP BVC");
1523 }
1524 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1525 setverdict(fail, "Different Paging received on SIGNALING BVC");
1526 }
1527 [] T.timeout {
1528 setverdict(pass);
1529 }
1530 }
1531}
1532
Harald Welte0e188242020-11-22 21:46:48 +01001533private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1534{
1535 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1536 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1537 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1538}
1539testcase TC_paging_cs_ptp_bss() runs on test_CT {
1540 var BSSGP_ConnHdlr vc_conn;
1541 f_init();
1542
1543 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1544 vc_conn.done;
1545
1546 f_cleanup();
1547}
1548
1549/* CS-PAGING on PTP-BVC for Location Area */
1550private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1551{
1552 var template (present) PDU_BSSGP exp_rx;
1553 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1554 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1555 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1556}
1557testcase TC_paging_cs_ptp_lac() runs on test_CT {
1558 var BSSGP_ConnHdlr vc_conn;
1559 f_init();
1560
1561 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1562 vc_conn.done;
1563
1564 f_cleanup();
1565}
1566
Harald Welte7462a592020-11-23 22:07:07 +01001567/* CS-PAGING on PTP-BVC for unknown Location Area */
1568private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1569{
1570 var GSM_Types.LocationAreaIdentification unknown_la := {
1571 mcc_mnc := '567F99'H,
1572 lac := 33333
1573 };
1574 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1575 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1576}
1577testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1578 var BSSGP_ConnHdlr vc_conn;
1579 f_init();
1580
1581 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1582 vc_conn.done;
1583
1584 f_cleanup();
1585}
1586
Harald Welte0e188242020-11-22 21:46:48 +01001587/* CS-PAGING on PTP-BVC for Routeing Area */
1588private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1589{
1590 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1591 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1592 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1593}
1594testcase TC_paging_cs_ptp_rac() runs on test_CT {
1595 var BSSGP_ConnHdlr vc_conn;
1596 f_init();
1597
1598 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1599 vc_conn.done;
1600
1601 f_cleanup();
1602}
1603
Harald Welte7462a592020-11-23 22:07:07 +01001604/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1605private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1606{
1607 var RoutingAreaIdentification unknown_ra := {
1608 lai := {
1609 mcc_mnc := '567F99'H,
1610 lac := 33333
1611 },
1612 rac := 254
1613 };
1614 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1615 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1616}
1617testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1618 var BSSGP_ConnHdlr vc_conn;
1619 f_init();
1620
1621 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1622 vc_conn.done;
1623
1624 f_cleanup();
1625}
1626
Harald Welte0e188242020-11-22 21:46:48 +01001627/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1628private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1629{
1630 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1631 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1632}
1633testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1634 var BSSGP_ConnHdlr vc_conn;
1635 f_init();
1636
1637 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1638 vc_conn.done;
1639
1640 f_cleanup();
1641}
1642
Harald Welte7462a592020-11-23 22:07:07 +01001643/* CS-PAGING on PTP-BVC for unknown BVCI */
1644private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1645{
1646 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1647 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1648}
1649testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1650 var BSSGP_ConnHdlr vc_conn;
1651 f_init();
1652
1653 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1654 vc_conn.done;
1655
1656 f_cleanup();
1657}
1658
Harald Welte0e188242020-11-22 21:46:48 +01001659/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1660private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1661 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1662{
1663 var template (present) PDU_BSSGP exp_rx;
1664 exp_rx := f_send_paging_cs(p4, 0, true);
1665
1666 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1667 var ro_default defaults := {};
1668 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1669 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1670 defaults := defaults & { d };
1671 }
1672 f_sleep(2.0);
1673 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1674 deactivate(defaults[i]);
1675 }
1676 log("Paging received on PCU ", g_roi);
1677
1678 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1679 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1680 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1681 if (exp_on_i and not rx_on_i) {
1682 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1683 }
1684 if (not exp_on_i and rx_on_i) {
1685 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1686 }
1687 }
1688 setverdict(pass);
1689}
1690
1691/* CS-PAGING on SIG-BVC for BSS Area */
1692private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1693{
1694 /* we expect the paging to arrive on all three NSE */
1695 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1696}
1697testcase TC_paging_cs_sig_bss() runs on test_CT {
1698 var BSSGP_ConnHdlr vc_conn;
1699 f_init();
1700
1701 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1702 vc_conn.done;
1703
1704 f_cleanup();
1705}
1706
1707/* CS-PAGING on SIG-BVC for Location Area */
1708private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1709{
1710 /* Both PCU index 0 and 1 have a BVC within the LAC */
1711 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1712}
1713testcase TC_paging_cs_sig_lac() runs on test_CT {
1714 var BSSGP_ConnHdlr vc_conn;
1715 f_init();
1716
1717 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1718 vc_conn.done;
1719
1720 f_cleanup();
1721}
1722
Harald Welte7462a592020-11-23 22:07:07 +01001723/* CS-PAGING on SIG-BVC for unknown Location Area */
1724private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1725{
1726 var GSM_Types.LocationAreaIdentification unknown_la := {
1727 mcc_mnc := '567F99'H,
1728 lac := 33333
1729 };
1730 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1731}
1732testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1733 var BSSGP_ConnHdlr vc_conn;
1734 f_init();
1735
1736 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1737 vc_conn.done;
1738
1739 f_cleanup();
1740}
1741
Harald Welte0e188242020-11-22 21:46:48 +01001742/* CS-PAGING on SIG-BVC for Routeing Area */
1743private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1744{
1745 /* Only PCU index 0 has a matching BVC within the LAC */
1746 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1747}
1748testcase TC_paging_cs_sig_rac() runs on test_CT {
1749 var BSSGP_ConnHdlr vc_conn;
1750 f_init();
1751
1752 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1753 vc_conn.done;
1754
1755 f_cleanup();
1756}
1757
Harald Welte7462a592020-11-23 22:07:07 +01001758/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1759private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1760{
1761 var RoutingAreaIdentification unknown_ra := {
1762 lai := {
1763 mcc_mnc := '567F99'H,
1764 lac := 33333
1765 },
1766 rac := 254
1767 };
1768 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1769}
1770testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1771 var BSSGP_ConnHdlr vc_conn;
1772 f_init();
1773
1774 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1775 vc_conn.done;
1776
1777 f_cleanup();
1778}
1779
Harald Welte0e188242020-11-22 21:46:48 +01001780/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1781private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1782{
1783 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1784}
1785testcase TC_paging_cs_sig_bvci() runs on test_CT {
1786 var BSSGP_ConnHdlr vc_conn;
1787 f_init();
1788
1789 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1790 vc_conn.done;
1791
1792 f_cleanup();
1793}
1794
Harald Welte7462a592020-11-23 22:07:07 +01001795/* CS-PAGING on SIG-BVC for unknown BVCI */
1796private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1797{
1798 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1799}
1800testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1801 var BSSGP_ConnHdlr vc_conn;
1802 f_init();
1803
1804 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1805 vc_conn.done;
1806
1807 f_cleanup();
1808}
1809
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001810private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1811 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1812 var integer i;
1813 for (i := 0; i < 10; i := i+1) {
1814 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1815 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1816 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1817
1818 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1819
1820 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1821 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1822 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1823
1824 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1825 }
1826 setverdict(pass);
1827}
1828testcase TC_flush_ll() runs on test_CT
1829{
1830 var BSSGP_ConnHdlr vc_conn;
1831 f_init();
1832
1833 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1834 vc_conn.done;
1835 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1836
1837 f_cleanup();
1838}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001839
Harald Welte239aa502020-11-24 23:14:20 +01001840private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1841{
1842 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1843 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1844 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1845
1846 SGSN_MGMT.clear;
1847 PCU_MGMT.clear;
1848
1849 /* block the PTP BVC from the PCU side */
1850 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
1851 /* expect state on both PCU and SGSN side to change */
1852 interleave {
1853 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
1854 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
1855 }
1856 setverdict(pass);
1857}
1858testcase TC_bvc_block_ptp() runs on test_CT
1859{
1860 f_init();
1861 f_sleep(1.0);
1862 f_block_ptp_bvc_from_pcu(0, 0);
1863 f_cleanup();
1864}
1865
1866private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1867{
1868 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1869 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1870 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1871
1872 SGSN_MGMT.clear;
1873 PCU_MGMT.clear;
1874
1875 /* block the PTP BVC from the PCU side */
1876 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
1877 /* expect state on both PCU and SGSN side to change */
1878 interleave {
1879 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
1880 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
1881 }
1882 setverdict(pass);
1883}
1884testcase TC_bvc_unblock_ptp() runs on test_CT
1885{
1886 f_init();
1887 f_sleep(1.0);
1888 f_block_ptp_bvc_from_pcu(0, 0);
1889 f_sleep(1.0);
1890 f_unblock_ptp_bvc_from_pcu(0, 0);
1891 f_cleanup();
1892}
1893
Harald Welte60a8ec72020-11-25 17:12:53 +01001894private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
1895[] pt.receive(BssgpStatusIndication:?) { repeat; }
1896}
1897private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
1898 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
1899 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
1900 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
1901 }
1902 }
1903 return null;
1904}
1905private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1906{
1907 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1908 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1909 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1910 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
1911 var default d;
1912
1913 SGSN_MGMT.clear;
1914 PCU_MGMT.clear;
1915
1916 /* block the PTP BVC from the PCU side */
1917 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
1918 /* expect state on both PCU and SGSN side to change */
1919 d := activate(as_ignore_status(SGSN_MGMT));
1920 interleave {
1921 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
1922 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
1923 }
1924 deactivate(d);
1925 setverdict(pass);
1926}
1927/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
1928testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
1929{
1930 f_init();
1931 f_sleep(3.0);
1932 f_reset_ptp_bvc_from_pcu(0, 0);
1933 f_cleanup();
1934}
1935
1936private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
1937{
1938 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1939 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1940 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1941 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
1942 var default d;
1943
1944 SGSN_MGMT.clear;
1945 PCU_MGMT.clear;
1946
1947 /* block the PTP BVC from the PCU side */
1948 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
1949 /* expect state on both PCU and SGSN side to change */
1950 d := activate(as_ignore_status(PCU_MGMT));
1951 interleave {
1952 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
1953 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
1954 }
1955 deactivate(d);
1956 setverdict(pass);
1957}
1958/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
1959testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
1960{
1961 f_init();
1962 f_sleep(3.0);
1963 f_reset_ptp_bvc_from_sgsn(0, 0);
1964 f_cleanup();
1965}
1966
Daniel Willmann423d8f42020-09-08 18:58:22 +02001967control {
1968 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01001969 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01001970 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01001971 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01001972 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01001973 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01001974 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01001975 execute( TC_resume() );
Harald Welte239aa502020-11-24 23:14:20 +01001976 execute( TC_bvc_block_ptp() );
1977 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01001978 execute( TC_bvc_reset_ptp_from_bss() );
1979 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Weltef8ef0282020-11-18 12:16:59 +01001980 if (false) {
1981 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
1982 execute( TC_load_sharing_dl() );
1983 }
Harald Welte0e188242020-11-22 21:46:48 +01001984
1985 /* PAGING-PS over PTP BVC */
1986 execute( TC_paging_ps_ptp_bss() );
1987 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001988 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001989 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001990 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001991 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01001992 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001993
1994 /* PAGING-PS over SIG BVC */
1995 execute( TC_paging_ps_sig_bss() );
1996 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001997 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001998 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001999 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002000 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002001 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002002
2003 /* PAGING-CS over PTP BVC */
2004 execute( TC_paging_cs_ptp_bss() );
2005 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002006 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002007 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002008 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002009 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002010 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002011
2012 /* PAGING-CS over SIG BVC */
2013 execute( TC_paging_cs_sig_bss() );
2014 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002015 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002016 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002017 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002018 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002019 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002020
2021
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002022 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002023}
2024
2025
2026}