blob: 48d2805d88edacd20e37a7aab4ec20c547bcb228 [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;
Harald Welte16786e92020-11-27 19:11:56 +0100219
220 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200221};
222
223type component BSSGP_ConnHdlr {
Harald Welte3dd21b32020-11-17 19:21:00 +0100224 /* array of per-BVC ports on the PCU side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200225 port BSSGP_PT PCU[NUM_PCU];
226 port BSSGP_PT PCU_SIG[NUM_PCU];
227 port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100228 /* component reference to the component to which we're currently connected */
229 var BSSGP_BVC_CT pcu_ct[NUM_PCU];
Harald Welte0e188242020-11-22 21:46:48 +0100230 /* BSSGP BVC configuration of the component to which we're currently connected */
231 var BssgpBvcConfig pcu_bvc_cfg[NUM_PCU];
Harald Welte3dd21b32020-11-17 19:21:00 +0100232
233 /* array of per-BVC ports on the SGSN side */
Daniel Willmann423d8f42020-09-08 18:58:22 +0200234 port BSSGP_PT SGSN[NUM_SGSN];
235 port BSSGP_PT SGSN_SIG[NUM_SGSN];
236 port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
Harald Welte3dd21b32020-11-17 19:21:00 +0100237 /* component reference to the component to which we're currently connected */
238 var BSSGP_BVC_CT sgsn_ct[NUM_PCU];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200239
240 var BSSGP_ConnHdlrPars g_pars;
241 timer g_Tguard;
242 var LLC_Entities llc;
Harald Welte0e188242020-11-22 21:46:48 +0100243
244 var ro_integer g_roi := {};
Daniel Willmann423d8f42020-09-08 18:58:22 +0200245}
246
247type record SGSN_ConnHdlrNetworkPars {
248 boolean expect_ptmsi,
249 boolean expect_auth,
250 boolean expect_ciph
251};
252
253type record BSSGP_ConnHdlrPars {
254 /* IMEI of the simulated ME */
255 hexstring imei,
256 /* IMSI of the simulated MS */
257 hexstring imsi,
258 /* MSISDN of the simulated MS (probably unused) */
259 hexstring msisdn,
260 /* P-TMSI allocated to the simulated MS */
261 OCT4 p_tmsi optional,
262 OCT3 p_tmsi_sig optional,
263 /* TLLI of the simulated MS */
264 OCT4 tlli,
265 OCT4 tlli_old optional,
266 RoutingAreaIdentificationV ra optional,
Harald Welte16357a92020-11-17 18:20:00 +0100267 GbInstances pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100268 GbInstances sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200269 float t_guard
270};
271
272private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
273 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
274 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
275
276 var RoutingAreaIdentificationV ret := {
277 mccDigit1 := mcc_mnc[0],
278 mccDigit2 := mcc_mnc[1],
279 mccDigit3 := mcc_mnc[2],
280 mncDigit3 := mcc_mnc[3],
281 mncDigit1 := mcc_mnc[4],
282 mncDigit2 := mcc_mnc[5],
283 lac := int2oct(cell_id.ra_id.lai.lac, 16),
284 rac := int2oct(cell_id.ra_id.rac, 8)
285 }
286 return ret;
287};
288
289private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100290 var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
291 var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
292 gb.vc_NS := NS_CT.create(ns_id);
293 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200294 /* connect lower end of BSSGP emulation with NS upper port */
295 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
296
Harald Welteb419d0e2020-11-16 16:45:05 +0100297 gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
298 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200299
300 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
301 connect(self:PROC, gb.vc_BSSGP:PROC);
302 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
303 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100304 connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200305 }
Harald Welte16786e92020-11-27 19:11:56 +0100306 connect(self:PCU_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200307}
308
309private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
Harald Welteb419d0e2020-11-16 16:45:05 +0100310 var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
311 var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
312 gb.vc_NS := NS_CT.create(ns_id);
313 gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200314 /* connect lower end of BSSGP emulation with NS upper port */
315 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
316
Harald Welteb419d0e2020-11-16 16:45:05 +0100317 gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
318 gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200319
320 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
321 connect(self:PROC, gb.vc_BSSGP:PROC);
322 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
323 disconnect(self:PROC, gb.vc_BSSGP:PROC);
Harald Weltefbae83f2020-11-15 23:25:55 +0100324 connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200325 }
Harald Welte16786e92020-11-27 19:11:56 +0100326 connect(self:SGSN_MGMT, gb.vc_BSSGP:MGMT);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200327}
328
329
330private function f_init_vty() runs on test_CT {
331 map(self:GBPVTY, system:GBPVTY);
332 f_vty_set_prompts(GBPVTY);
333 f_vty_transceive(GBPVTY, "enable");
334}
335
Harald Weltefbae83f2020-11-15 23:25:55 +0100336type record of integer ro_integer;
337
338private function ro_integer_contains(ro_integer r, integer x) return boolean {
339 for (var integer j := 0; j < lengthof(r); j := j+1) {
340 if (r[j] == x) {
341 return true;
342 }
343 }
344 return false;
345}
346
Harald Welte6d63f742020-11-15 19:44:04 +0100347function f_init() runs on test_CT {
Harald Weltefbae83f2020-11-15 23:25:55 +0100348 var ro_integer bvci_unblocked := {};
349 var BssgpStatusIndication bsi;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200350 var integer i;
351
352 if (g_initialized == true) {
353 return;
354 }
355 g_initialized := true;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200356
357 g_sgsn[0].cfg := {
Harald Welte6d63f742020-11-15 19:44:04 +0100358 nsei := mp_nsconfig_sgsn[0].nsei,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200359 sgsn_role := true,
Harald Welte6d63f742020-11-15 19:44:04 +0100360 bvc := { }
361 }
362 for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
363 g_pcu[i].cfg := mp_gbconfigs[i];
364 /* concatenate all the PCU-side BVCs for the SGSN side */
365 g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & mp_gbconfigs[i].bvc;
366 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200367
368 f_init_vty();
Harald Welte6d63f742020-11-15 19:44:04 +0100369 for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
Daniel Willmann443fc572020-11-18 13:26:57 +0100370 f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
Harald Welteea1ba592020-11-17 18:05:13 +0100371 f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100372 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200373 f_sleep(4.0);
Harald Welte6d63f742020-11-15 19:44:04 +0100374 for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
Harald Welteb419d0e2020-11-16 16:45:05 +0100375 f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
Harald Welte6d63f742020-11-15 19:44:04 +0100376 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100377
378 /* wait until all BVC are unblocked on both sides */
Harald Welted2801272020-11-17 19:22:58 +0100379 timer T := 15.0;
Harald Weltefbae83f2020-11-15 23:25:55 +0100380 T.start;
381 alt {
382 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
383 bvci_unblocked := bvci_unblocked & { bsi.bvci };
384 if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
385 repeat;
386 }
387 }
388 [] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
389 repeat;
390 }
Harald Welte3c905152020-11-26 20:56:09 +0100391 [] SGSN_MGMT.receive(BssgpResetIndication:?) {
392 repeat;
393 }
Harald Weltefbae83f2020-11-15 23:25:55 +0100394 [] SGSN_MGMT.receive {
395 setverdict(fail, "Received unexpected message on SGSN_MGMT");
396 mtc.stop;
397 }
398
399 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
400 repeat;
401 }
402 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
403 repeat;
404 }
405 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
406 repeat;
407 }
408 [] PCU_MGMT.receive {
409 setverdict(fail, "Received unexpected message on PCU_MGMT");
410 mtc.stop;
411 }
412
413 [] T.timeout {
414 setverdict(fail, "Timeout waiting for unblock of all BVCs");
415 mtc.stop;
416 }
417 }
418
419 /* iterate over list and check all BVCI */
420 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
421 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
422 if (not ro_integer_contains(bvci_unblocked, bvci)) {
423 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
424 mtc.stop;
425 }
426 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200427}
428
429function f_cleanup() runs on test_CT {
430 self.stop;
431}
432
433type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
434
435/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100436function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200437 float t_guard := 30.0)
438runs on test_CT return BSSGP_ConnHdlr {
439 var BSSGP_ConnHdlr vc_conn;
440
441 var BSSGP_ConnHdlrPars pars := {
442 imei := f_gen_imei(imsi_suffix),
443 imsi := f_gen_imsi(imsi_suffix),
444 msisdn := f_gen_msisdn(imsi_suffix),
445 p_tmsi := omit,
446 p_tmsi_sig := omit,
447 tlli := f_gprs_tlli_random(),
448 tlli_old := omit,
449 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100450 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100451 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200452 t_guard := t_guard
453 };
454
455 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200456
457 vc_conn.start(f_handler_init(fn, id, pars));
458 return vc_conn;
459}
460
Harald Welte3dd21b32020-11-17 19:21:00 +0100461/* 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 +0100462private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
463runs on BSSGP_ConnHdlr {
464 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100465 if (PCU[port_idx].checkstate("Connected")) {
466 /* unregister + disconnect from old BVC */
467 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
468 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
469 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
470 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
471 }
472 /* connect to new BVC and register us */
473 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
474 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
475 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
476 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
477 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100478 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100479}
480
481/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
482private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
483 if (SGSN[port_idx].checkstate("Connected")) {
484 /* unregister + disconnect from old BVC */
485 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
486 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
487 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
488 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
489 }
490 /* connect to new BVC and register us */
491 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
492 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
493 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
494 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
495 sgsn_ct[port_idx] := bvc_ct;
496}
497
Daniel Willmann423d8f42020-09-08 18:58:22 +0200498private altstep as_Tguard() runs on BSSGP_ConnHdlr {
499 [] g_Tguard.timeout {
500 setverdict(fail, "Tguard timeout");
501 mtc.stop;
502 }
503}
504
505/* first function called in every ConnHdlr */
506private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
507runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100508 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200509 /* do some common stuff like setting up g_pars */
510 g_pars := pars;
511
512 llc := f_llc_create(false);
513
Harald Welte3dd21b32020-11-17 19:21:00 +0100514 /* default connections on PCU side: First BVC of each NSE/PCU */
515 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100516 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100517 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100518
519 /* default connections on SGSN side: First BVC of each NSE/SGSN */
520 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
521 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100522 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200523
524 g_Tguard.start(pars.t_guard);
525 activate(as_Tguard());
526
527 /* call the user-supplied test case function */
528 fn.apply(id);
529}
530
Harald Welte1e834f32020-11-15 20:02:59 +0100531private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
532runs on BSSGP_ConnHdlr {
533 PT.call(BSSGP_register_client:{imsi, tlli}) {
534 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
535 }
536}
537
538private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
539runs on BSSGP_ConnHdlr {
540 PT.call(BSSGP_unregister_client:{imsi}) {
541 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
542 }
543}
544
Harald Welte22ef5d92020-11-16 13:35:14 +0100545/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
546friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100547 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100548 var PDU_BSSGP rx;
549 timer T := 1.0;
550
Daniel Willmann4798fd72020-11-24 16:23:29 +0100551 if (use_sig) {
552 PCU_SIG[pcu_idx].send(tx);
553 } else {
554 PCU[pcu_idx].send(tx);
555 }
556
Harald Welte22ef5d92020-11-16 13:35:14 +0100557 T.start;
558 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100559 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
560 setverdict(pass);
561 }
562 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100563 setverdict(pass);
564 }
565 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
566 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
567 mtc.stop;
568 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100569 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
570 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
571 mtc.stop;
572 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100573 [] T.timeout {
574 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
575 mtc.stop;
576 }
577 }
578}
579
580/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
581friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100582 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100583 var PDU_BSSGP rx;
584 timer T := 1.0;
585
Daniel Willmann4798fd72020-11-24 16:23:29 +0100586 if (use_sig) {
587 SGSN_SIG[sgsn_idx].send(tx);
588 } else {
589 SGSN[sgsn_idx].send(tx);
590 }
591
Harald Welte22ef5d92020-11-16 13:35:14 +0100592 T.start;
593 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100594 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
595 setverdict(pass);
596 }
597 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100598 setverdict(pass);
599 }
600 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
601 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
602 mtc.stop;
603 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100604 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
605 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
606 mtc.stop;
607 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100608 [] T.timeout {
609 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
610 mtc.stop;
611 }
612 }
613}
Harald Welte1e834f32020-11-15 20:02:59 +0100614
Harald Welte3807ed12020-11-24 19:05:22 +0100615/***********************************************************************
616 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
617 ***********************************************************************/
618
619type component GlobalTest_CT extends test_CT {
620 port BSSGP_PT G_PCU[NUM_PCU];
621 port BSSGP_PT G_SGSN[NUM_SGSN];
622};
623
624private function f_global_init() runs on GlobalTest_CT {
625 var integer i;
626 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
627 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
628 }
629 for (i := 0; i < lengthof(g_pcu); i := i+1) {
630 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
631 }
632}
633
634/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
635friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
636 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
637 var PDU_BSSGP rx;
638 timer T := 1.0;
639
640 G_PCU[pcu_idx].send(tx);
641 T.start;
642 alt {
643 [] G_SGSN[sgsn_idx].receive(exp_rx) {
644 setverdict(pass);
645 }
646 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
647 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
648 mtc.stop;
649 }
650 [] T.timeout {
651 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
652 mtc.stop;
653 }
654 }
655}
656
657/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
658friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
659 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
660 var PDU_BSSGP rx;
661 timer T := 1.0;
662
663 G_SGSN[sgsn_idx].send(tx);
664 T.start;
665 alt {
666 [] G_PCU[pcu_idx].receive(exp_rx) {
667 setverdict(pass);
668 }
669 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
670 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
671 mtc.stop;
672 }
673 [] T.timeout {
674 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
675 mtc.stop;
676 }
677 }
678}
679
680
Daniel Willmann423d8f42020-09-08 18:58:22 +0200681/* TODO:
682 * Detach without Attach
683 * SM procedures without attach / RAU
684 * ATTACH / RAU
685 ** with / without authentication
686 ** with / without P-TMSI allocation
687 * re-transmissions of LLC frames
688 * PDP Context activation
689 ** with different GGSN config in SGSN VTY
690 ** with different PDP context type (v4/v6/v46)
691 ** timeout from GGSN
692 ** multiple / secondary PDP context
693 */
694
695private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
696 f_sleep(5.0);
697 setverdict(pass);
698}
699
700testcase TC_BVC_bringup() runs on test_CT {
701 var BSSGP_ConnHdlr vc_conn;
702 f_init();
703
704 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
705 vc_conn.done;
706
707 f_cleanup();
708}
709
710friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100711 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200712 timer T := 5.0;
713 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100714 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200715 T.start;
716 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100717 [] 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 +0200718 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
719 }
Harald Welte16357a92020-11-17 18:20:00 +0100720 [] 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 +0200721 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
722 mtc.stop;
723 }
724 [] T.timeout {
725 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
726 mtc.stop;
727 }
728 }
729 return '00'O;
730}
731
732friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100733 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200734 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100735 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 +0200736 T.start;
737 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100738 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
739 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200740 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
741 mtc.stop;
742 }
743 [] T.timeout {
744 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
745 mtc.stop;
746 }
747 }
748}
749
750
Harald Welte92686012020-11-15 21:45:49 +0100751/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
752private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100753 var integer ran_idx := 0;
754 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100755 var integer i;
756
757 for (i := 0; i < 1024; i := i+1) {
758 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100759 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 +0100760 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100761 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 +0100762
Harald Welte22ef5d92020-11-16 13:35:14 +0100763 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100764 }
765 setverdict(pass);
766}
767
768testcase TC_ul_unitdata() runs on test_CT
769{
770 var BSSGP_ConnHdlr vc_conn;
771 f_init();
772
773 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
774 vc_conn.done;
775 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
776
777 f_cleanup();
778}
779
Harald Welte78d8db92020-11-15 23:27:27 +0100780/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
781private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
782 var integer i;
783
784 for (i := 0; i < 1024; i := i+1) {
785 var octetstring payload := f_rnd_octstring(i);
786 var template (value) PDU_BSSGP pdu_tx :=
787 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
788 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
789 var template (present) PDU_BSSGP pdu_rx :=
790 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
791
Harald Welte22ef5d92020-11-16 13:35:14 +0100792 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100793 }
794 setverdict(pass);
795}
796
797testcase TC_dl_unitdata() runs on test_CT
798{
799 var BSSGP_ConnHdlr vc_conn;
800 f_init();
801
802 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
803 vc_conn.done;
804 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
805
806 f_cleanup();
807}
Harald Welte92686012020-11-15 21:45:49 +0100808
Harald Welte6dc2ac42020-11-16 09:16:17 +0100809private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
810 var integer i;
811
812 for (i := 0; i < 10; i := i+1) {
813 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
814 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
815 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
816
Harald Welte22ef5d92020-11-16 13:35:14 +0100817 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100818 }
819 setverdict(pass);
820}
821testcase TC_ra_capability() runs on test_CT
822{
823 var BSSGP_ConnHdlr vc_conn;
824 f_init();
825
826 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
827 vc_conn.done;
828 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
829
830 f_cleanup();
831}
832
Daniel Willmannace3ece2020-11-16 19:53:26 +0100833private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
834 var integer i;
835 var OCT1 tag;
836 for (i := 0; i < 10; i := i+1) {
837 tag := int2oct(23 + i, 1);
838 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
839 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
840 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
841
842 f_pcu2sgsn(pdu_tx, pdu_rx);
843
844 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
845 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
846 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
847
848 f_sgsn2pcu(pdu_tx, pdu_rx);
849 }
850 setverdict(pass);
851}
852testcase TC_ra_capability_upd() runs on test_CT
853{
854 var BSSGP_ConnHdlr vc_conn;
855 f_init();
856
Daniel Willmann54833f22020-11-19 15:43:52 +0100857 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100858 vc_conn.done;
859 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
860
861 f_cleanup();
862}
863
Daniel Willmann165d6612020-11-19 14:27:29 +0100864private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
865 var integer i;
866 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
867 for (i := 0; i < 10; i := i+1) {
868 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
869 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
870 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
871
872 f_pcu2sgsn(pdu_tx, pdu_rx);
873 }
874 setverdict(pass);
875}
876testcase TC_radio_status() runs on test_CT
877{
878 var BSSGP_ConnHdlr vc_conn;
879 f_init();
880
Daniel Willmann54833f22020-11-19 15:43:52 +0100881 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100882 vc_conn.done;
883 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
884
885 f_cleanup();
886}
887
Harald Welte3807ed12020-11-24 19:05:22 +0100888private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100889 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100890
Daniel Willmannfa67f492020-11-19 15:48:05 +0100891 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100892 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100893 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100894 var OCT4 tlli := f_gprs_tlli_random();
895 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100896 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100897 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100898
Harald Welte3807ed12020-11-24 19:05:22 +0100899 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100900
Harald Welte3807ed12020-11-24 19:05:22 +0100901 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100902 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100903 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100904
Harald Welte3807ed12020-11-24 19:05:22 +0100905 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100906
907 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100908 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100909 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100910 pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100911
Harald Welte3807ed12020-11-24 19:05:22 +0100912 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100913 }
914 setverdict(pass);
915}
Harald Welte3807ed12020-11-24 19:05:22 +0100916testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100917{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100918 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100919 f_global_init();
920 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +0100921 f_cleanup();
922}
Harald Welte6dc2ac42020-11-16 09:16:17 +0100923
Harald Welte3807ed12020-11-24 19:05:22 +0100924private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +0100925 var integer i;
926
927 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100928 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +0100929 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100930 var OCT4 tlli := f_gprs_tlli_random();
931 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100932 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100933 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100934
Harald Welte3807ed12020-11-24 19:05:22 +0100935 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100936
Harald Welte3807ed12020-11-24 19:05:22 +0100937 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100938 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100939 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100940
Harald Welte3807ed12020-11-24 19:05:22 +0100941 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100942
943 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100944 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100945 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100946 pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100947
Harald Welte3807ed12020-11-24 19:05:22 +0100948 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100949 }
950 setverdict(pass);
951}
Harald Welte3807ed12020-11-24 19:05:22 +0100952testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +0100953{
Daniel Willmann087a33d2020-11-19 15:58:43 +0100954 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100955 f_global_init();
956 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +0100957 f_cleanup();
958}
959
Harald Weltef8ef0282020-11-18 12:16:59 +0100960/* test the load-sharing between multiple NS-VC on the BSS side */
961private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
962 var integer i;
963
964 for (i := 0; i < 10; i := i+1) {
965 var octetstring payload := f_rnd_octstring(i);
966 var template (value) PDU_BSSGP pdu_tx :=
967 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
968 SGSN[0].send(pdu_tx);
969 }
970 setverdict(pass);
971}
972testcase TC_load_sharing_dl() runs on test_CT_NS
973{
974 const integer num_ue := 10;
975 var BSSGP_ConnHdlr vc_conn[num_ue];
976 f_init();
977
978 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
979 * side so we get the raw NsUnitdataIndication and hence observe different
980 * NSVCI */
981 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
982 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
983
984 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
985 * of the NS-VC is ALIVE/UNBLOCKED */
986 f_sleep(3.0);
987
988 /* start parallel components generating DL-UNITDATA from the SGSN side */
989 for (var integer i:= 0; i < num_ue; i := i+1) {
990 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
991 }
992
993 /* now start counting all the messages that were queued before */
994 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
995 var ro_integer rx_count := { 0, 0, 0, 0 };
996 timer T := 2.0;
997 T.start;
998 alt {
999 [] as_NsUdiCount(0, rx_count);
1000 [] as_NsUdiCount(1, rx_count);
1001 [] as_NsUdiCount(2, rx_count);
1002 [] as_NsUdiCount(3, rx_count);
1003 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
1004 [] NS.receive(NsStatusIndication:?) { repeat; }
1005 [] NS.receive {
1006 setverdict(fail, "Rx unexpected NS");
1007 mtc.stop;
1008 }
1009 [] T.timeout {
1010 }
1011 }
1012 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1013 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1014 if (rx_count[i] == 0) {
1015 setverdict(fail, "Data not shared over all NSVC");
1016 }
1017 }
1018 setverdict(pass);
1019}
1020private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1021 var NsUnitdataIndication udi;
1022 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1023 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1024 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1025 repeat;
1026 }
1027}
1028type component test_CT_NS extends test_CT {
1029 port NS_PT NS;
1030};
1031
1032
Harald Welte0e188242020-11-22 21:46:48 +01001033/***********************************************************************
1034 * PAGING PS procedure
1035 ***********************************************************************/
1036
1037private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1038 boolean use_sig := false)
1039runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1040 var template (value) PDU_BSSGP pdu_tx;
1041 var template (present) PDU_BSSGP pdu_rx;
1042 /* we always specify '0' as BVCI in the templates below, as we override it with
1043 * 'p4' later anyway */
1044 pdu_rx := tr_BSSGP_PS_PAGING(0);
1045 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1046 if (ispresent(g_pars.p_tmsi)) {
1047 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1048 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1049 } else {
1050 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1051 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1052 }
1053 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1054 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1055 if (use_sig == false) {
1056 SGSN[sgsn_idx].send(pdu_tx);
1057 } else {
1058 SGSN_SIG[sgsn_idx].send(pdu_tx);
1059 }
1060 return pdu_rx;
1061}
1062
1063/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1064 * specified PCU index */
1065private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1066 boolean use_sig := false,integer pcu_idx := 0)
1067runs on BSSGP_ConnHdlr {
1068 var template (present) PDU_BSSGP exp_rx;
1069 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1070 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1071 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1072 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1073 timer T := 2.0;
1074 T.start;
1075 alt {
1076 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1077 setverdict(pass);
1078 repeat;
1079 }
1080 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1081 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1082 }
1083 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1084 setverdict(pass);
1085 repeat;
1086 }
1087 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1088 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1089 }
1090 [] any from PCU.receive(exp_rx) {
1091 setverdict(fail, "Paging received on unexpected BVC");
1092 }
1093 [] any from PCU_SIG.receive(exp_rx) {
1094 setverdict(fail, "Paging received on unexpected BVC");
1095 }
1096 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1097 setverdict(fail, "Different Paging than expected received PTP BVC");
1098 }
1099 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1100 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1101 }
1102 [] T.timeout;
1103 }
1104}
1105
Harald Welte7462a592020-11-23 22:07:07 +01001106/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1107private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1108 boolean use_sig := false)
1109runs on BSSGP_ConnHdlr {
1110 var template (present) PDU_BSSGP exp_rx;
1111 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1112 /* Expect paging to propagate to no BSS */
1113 timer T := 2.0;
1114 T.start;
1115 alt {
1116 [] any from PCU.receive(exp_rx) {
1117 setverdict(fail, "Paging received on unexpected BVC");
1118 }
1119 [] any from PCU_SIG.receive(exp_rx) {
1120 setverdict(fail, "Paging received on unexpected BVC");
1121 }
1122 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1123 setverdict(fail, "Different Paging received on PTP BVC");
1124 }
1125 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1126 setverdict(fail, "Different Paging received on SIGNALING BVC");
1127 }
1128 [] T.timeout {
1129 setverdict(pass);
1130 }
1131 }
1132}
1133
Harald Welte0e188242020-11-22 21:46:48 +01001134private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1135{
1136 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1137 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1138 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1139}
1140testcase TC_paging_ps_ptp_bss() runs on test_CT {
1141 var BSSGP_ConnHdlr vc_conn;
1142 f_init();
1143
1144 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1145 vc_conn.done;
1146
1147 f_cleanup();
1148}
1149
1150/* PS-PAGING on PTP-BVC for Location Area */
1151private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1152{
1153 var template (present) PDU_BSSGP exp_rx;
1154 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1155 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1156 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1157}
1158testcase TC_paging_ps_ptp_lac() runs on test_CT {
1159 var BSSGP_ConnHdlr vc_conn;
1160 f_init();
1161
1162 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1163 vc_conn.done;
1164
1165 f_cleanup();
1166}
1167
Harald Welte7462a592020-11-23 22:07:07 +01001168/* PS-PAGING on PTP-BVC for unknown Location Area */
1169private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1170{
1171 var GSM_Types.LocationAreaIdentification unknown_la := {
1172 mcc_mnc := '567F99'H,
1173 lac := 33333
1174 };
1175 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1176 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1177}
1178testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1179 var BSSGP_ConnHdlr vc_conn;
1180 f_init();
1181
1182 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1183 vc_conn.done;
1184
1185 f_cleanup();
1186}
1187
Harald Welte0e188242020-11-22 21:46:48 +01001188/* PS-PAGING on PTP-BVC for Routeing Area */
1189private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1190{
1191 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1192 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1193 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1194}
1195testcase TC_paging_ps_ptp_rac() runs on test_CT {
1196 var BSSGP_ConnHdlr vc_conn;
1197 f_init();
1198
1199 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1200 vc_conn.done;
1201
1202 f_cleanup();
1203}
1204
Harald Welte7462a592020-11-23 22:07:07 +01001205/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1206private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1207{
1208 var RoutingAreaIdentification unknown_ra := {
1209 lai := {
1210 mcc_mnc := '567F99'H,
1211 lac := 33333
1212 },
1213 rac := 254
1214 };
1215 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1216 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1217}
1218testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1219 var BSSGP_ConnHdlr vc_conn;
1220 f_init();
1221
1222 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1223 vc_conn.done;
1224
1225 f_cleanup();
1226}
1227
Harald Welte0e188242020-11-22 21:46:48 +01001228/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1229private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1230{
1231 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1232 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1233}
1234testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1235 var BSSGP_ConnHdlr vc_conn;
1236 f_init();
1237
1238 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1239 vc_conn.done;
1240
1241 f_cleanup();
1242}
1243
Harald Welte7462a592020-11-23 22:07:07 +01001244/* PS-PAGING on PTP-BVC for unknown BVCI */
1245private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1246{
1247 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1248 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1249}
1250testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1251 var BSSGP_ConnHdlr vc_conn;
1252 f_init();
1253
1254 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1255 vc_conn.done;
1256
1257 f_cleanup();
1258}
1259
Harald Welte0e188242020-11-22 21:46:48 +01001260/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1261private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1262runs on BSSGP_ConnHdlr {
1263[] PCU_SIG[pcu_idx].receive(exp_rx) {
1264 if (ro_integer_contains(roi, pcu_idx)) {
1265 setverdict(fail, "Received multiple paging on same SIG BVC");
1266 }
1267 roi := roi & { pcu_idx };
1268 repeat;
1269 }
1270[] PCU[pcu_idx].receive(exp_rx) {
1271 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1272 }
1273[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1274 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1275 }
1276[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1277 setverdict(fail, "Different Paging than expected received PTP BVC");
1278 }
1279}
1280
1281type record of default ro_default;
1282
1283/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1284private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1285 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1286{
1287 var template (present) PDU_BSSGP exp_rx;
1288 exp_rx := f_send_paging_ps(p4, 0, true);
1289
1290 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1291 var ro_default defaults := {};
1292 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1293 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1294 defaults := defaults & { d };
1295 }
1296 f_sleep(2.0);
1297 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1298 deactivate(defaults[i]);
1299 }
1300 log("Paging received on PCU ", g_roi);
1301
1302 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1303 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1304 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1305 if (exp_on_i and not rx_on_i) {
1306 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1307 }
1308 if (not exp_on_i and rx_on_i) {
1309 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1310 }
1311 }
1312 setverdict(pass);
1313}
1314
1315/* PS-PAGING on SIG-BVC for BSS Area */
1316private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1317{
1318 /* we expect the paging to arrive on all three NSE */
1319 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1320}
1321testcase TC_paging_ps_sig_bss() 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_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1326 vc_conn.done;
1327
1328 f_cleanup();
1329}
1330
1331/* PS-PAGING on SIG-BVC for Location Area */
1332private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1333{
1334 /* Both PCU index 0 and 1 have a BVC within the LAC */
1335 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1336}
1337testcase TC_paging_ps_sig_lac() runs on test_CT {
1338 var BSSGP_ConnHdlr vc_conn;
1339 f_init();
1340
1341 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1342 vc_conn.done;
1343
1344 f_cleanup();
1345}
1346
Harald Welte7462a592020-11-23 22:07:07 +01001347/* PS-PAGING on SIG-BVC for unknown Location Area */
1348private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1349{
1350 var GSM_Types.LocationAreaIdentification unknown_la := {
1351 mcc_mnc := '567F99'H,
1352 lac := 33333
1353 };
1354 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1355}
1356testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1357 var BSSGP_ConnHdlr vc_conn;
1358 f_init();
1359
1360 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1361 vc_conn.done;
1362
1363 f_cleanup();
1364}
1365
Harald Welte0e188242020-11-22 21:46:48 +01001366/* PS-PAGING on SIG-BVC for Routeing Area */
1367private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1368{
1369 /* Only PCU index 0 has a matching BVC within the LAC */
1370 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1371}
1372testcase TC_paging_ps_sig_rac() runs on test_CT {
1373 var BSSGP_ConnHdlr vc_conn;
1374 f_init();
1375
1376 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1377 vc_conn.done;
1378
1379 f_cleanup();
1380}
1381
Harald Welte7462a592020-11-23 22:07:07 +01001382/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1383private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1384{
1385 var RoutingAreaIdentification unknown_ra := {
1386 lai := {
1387 mcc_mnc := '567F99'H,
1388 lac := 33333
1389 },
1390 rac := 254
1391 };
1392 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1393}
1394testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1395 var BSSGP_ConnHdlr vc_conn;
1396 f_init();
1397
1398 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1399 vc_conn.done;
1400
1401 f_cleanup();
1402}
1403
Harald Welte0e188242020-11-22 21:46:48 +01001404/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1405private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1406{
1407 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1408}
1409testcase TC_paging_ps_sig_bvci() runs on test_CT {
1410 var BSSGP_ConnHdlr vc_conn;
1411 f_init();
1412
1413 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1414 vc_conn.done;
1415
1416 f_cleanup();
1417}
1418
Harald Welte7462a592020-11-23 22:07:07 +01001419/* PS-PAGING on SIG-BVC for unknown BVCI */
1420private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1421{
1422 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1423}
1424testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1425 var BSSGP_ConnHdlr vc_conn;
1426 f_init();
1427
1428 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1429 vc_conn.done;
1430
1431 f_cleanup();
1432}
1433
1434
Harald Welte0e188242020-11-22 21:46:48 +01001435
1436/***********************************************************************
1437 * PAGING CS procedure
1438 ***********************************************************************/
1439
1440private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1441 boolean use_sig := false)
1442runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1443 var template (value) PDU_BSSGP pdu_tx;
1444 var template (present) PDU_BSSGP pdu_rx;
1445 /* we always specify '0' as BVCI in the templates below, as we override it with
1446 * 'p4' later anyway */
1447 pdu_rx := tr_BSSGP_CS_PAGING(0);
1448 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1449 if (ispresent(g_pars.p_tmsi)) {
1450 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1451 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1452 } else {
1453 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1454 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1455 }
1456 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1457 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1458 if (use_sig == false) {
1459 SGSN[sgsn_idx].send(pdu_tx);
1460 } else {
1461 SGSN_SIG[sgsn_idx].send(pdu_tx);
1462 }
1463 return pdu_rx;
1464}
1465
1466/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1467 * specified PCU index */
1468private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1469 boolean use_sig := false,integer pcu_idx := 0)
1470runs on BSSGP_ConnHdlr {
1471 var template (present) PDU_BSSGP exp_rx;
1472 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1473 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1474 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1475 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1476 timer T := 2.0;
1477 T.start;
1478 alt {
1479 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1480 setverdict(pass);
1481 repeat;
1482 }
1483 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1484 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1485 }
1486 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1487 setverdict(pass);
1488 repeat;
1489 }
1490 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1491 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1492 }
1493 [] any from PCU.receive(exp_rx) {
1494 setverdict(fail, "Paging received on unexpected BVC");
1495 }
1496 [] any from PCU_SIG.receive(exp_rx) {
1497 setverdict(fail, "Paging received on unexpected BVC");
1498 }
1499 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1500 setverdict(fail, "Different Paging than expected received PTP BVC");
1501 }
1502 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1503 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1504 }
1505 [] T.timeout;
1506 }
1507}
1508
Harald Welte7462a592020-11-23 22:07:07 +01001509/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1510private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1511 boolean use_sig := false)
1512runs on BSSGP_ConnHdlr {
1513 var template (present) PDU_BSSGP exp_rx;
1514 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1515 /* Expect paging to propagate to no BSS */
1516 timer T := 2.0;
1517 T.start;
1518 alt {
1519 [] any from PCU.receive(exp_rx) {
1520 setverdict(fail, "Paging received on unexpected BVC");
1521 }
1522 [] any from PCU_SIG.receive(exp_rx) {
1523 setverdict(fail, "Paging received on unexpected BVC");
1524 }
1525 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1526 setverdict(fail, "Different Paging received on PTP BVC");
1527 }
1528 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1529 setverdict(fail, "Different Paging received on SIGNALING BVC");
1530 }
1531 [] T.timeout {
1532 setverdict(pass);
1533 }
1534 }
1535}
1536
Harald Welte0e188242020-11-22 21:46:48 +01001537private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1538{
1539 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1540 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1541 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1542}
1543testcase TC_paging_cs_ptp_bss() runs on test_CT {
1544 var BSSGP_ConnHdlr vc_conn;
1545 f_init();
1546
1547 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1548 vc_conn.done;
1549
1550 f_cleanup();
1551}
1552
1553/* CS-PAGING on PTP-BVC for Location Area */
1554private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1555{
1556 var template (present) PDU_BSSGP exp_rx;
1557 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1558 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1559 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1560}
1561testcase TC_paging_cs_ptp_lac() runs on test_CT {
1562 var BSSGP_ConnHdlr vc_conn;
1563 f_init();
1564
1565 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1566 vc_conn.done;
1567
1568 f_cleanup();
1569}
1570
Harald Welte7462a592020-11-23 22:07:07 +01001571/* CS-PAGING on PTP-BVC for unknown Location Area */
1572private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1573{
1574 var GSM_Types.LocationAreaIdentification unknown_la := {
1575 mcc_mnc := '567F99'H,
1576 lac := 33333
1577 };
1578 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1579 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1580}
1581testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1582 var BSSGP_ConnHdlr vc_conn;
1583 f_init();
1584
1585 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1586 vc_conn.done;
1587
1588 f_cleanup();
1589}
1590
Harald Welte0e188242020-11-22 21:46:48 +01001591/* CS-PAGING on PTP-BVC for Routeing Area */
1592private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1593{
1594 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1595 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1596 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1597}
1598testcase TC_paging_cs_ptp_rac() runs on test_CT {
1599 var BSSGP_ConnHdlr vc_conn;
1600 f_init();
1601
1602 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1603 vc_conn.done;
1604
1605 f_cleanup();
1606}
1607
Harald Welte7462a592020-11-23 22:07:07 +01001608/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1609private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1610{
1611 var RoutingAreaIdentification unknown_ra := {
1612 lai := {
1613 mcc_mnc := '567F99'H,
1614 lac := 33333
1615 },
1616 rac := 254
1617 };
1618 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1619 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1620}
1621testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1622 var BSSGP_ConnHdlr vc_conn;
1623 f_init();
1624
1625 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1626 vc_conn.done;
1627
1628 f_cleanup();
1629}
1630
Harald Welte0e188242020-11-22 21:46:48 +01001631/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1632private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1633{
1634 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1635 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1636}
1637testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1638 var BSSGP_ConnHdlr vc_conn;
1639 f_init();
1640
1641 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1642 vc_conn.done;
1643
1644 f_cleanup();
1645}
1646
Harald Welte7462a592020-11-23 22:07:07 +01001647/* CS-PAGING on PTP-BVC for unknown BVCI */
1648private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1649{
1650 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1651 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1652}
1653testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1654 var BSSGP_ConnHdlr vc_conn;
1655 f_init();
1656
1657 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1658 vc_conn.done;
1659
1660 f_cleanup();
1661}
1662
Harald Welte0e188242020-11-22 21:46:48 +01001663/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1664private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1665 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1666{
1667 var template (present) PDU_BSSGP exp_rx;
1668 exp_rx := f_send_paging_cs(p4, 0, true);
1669
1670 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1671 var ro_default defaults := {};
1672 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1673 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1674 defaults := defaults & { d };
1675 }
1676 f_sleep(2.0);
1677 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1678 deactivate(defaults[i]);
1679 }
1680 log("Paging received on PCU ", g_roi);
1681
1682 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1683 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1684 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1685 if (exp_on_i and not rx_on_i) {
1686 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1687 }
1688 if (not exp_on_i and rx_on_i) {
1689 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1690 }
1691 }
1692 setverdict(pass);
1693}
1694
1695/* CS-PAGING on SIG-BVC for BSS Area */
1696private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1697{
1698 /* we expect the paging to arrive on all three NSE */
1699 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1700}
1701testcase TC_paging_cs_sig_bss() runs on test_CT {
1702 var BSSGP_ConnHdlr vc_conn;
1703 f_init();
1704
1705 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1706 vc_conn.done;
1707
1708 f_cleanup();
1709}
1710
1711/* CS-PAGING on SIG-BVC for Location Area */
1712private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1713{
1714 /* Both PCU index 0 and 1 have a BVC within the LAC */
1715 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1716}
1717testcase TC_paging_cs_sig_lac() runs on test_CT {
1718 var BSSGP_ConnHdlr vc_conn;
1719 f_init();
1720
1721 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1722 vc_conn.done;
1723
1724 f_cleanup();
1725}
1726
Harald Welte7462a592020-11-23 22:07:07 +01001727/* CS-PAGING on SIG-BVC for unknown Location Area */
1728private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1729{
1730 var GSM_Types.LocationAreaIdentification unknown_la := {
1731 mcc_mnc := '567F99'H,
1732 lac := 33333
1733 };
1734 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1735}
1736testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1737 var BSSGP_ConnHdlr vc_conn;
1738 f_init();
1739
1740 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1741 vc_conn.done;
1742
1743 f_cleanup();
1744}
1745
Harald Welte0e188242020-11-22 21:46:48 +01001746/* CS-PAGING on SIG-BVC for Routeing Area */
1747private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1748{
1749 /* Only PCU index 0 has a matching BVC within the LAC */
1750 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1751}
1752testcase TC_paging_cs_sig_rac() runs on test_CT {
1753 var BSSGP_ConnHdlr vc_conn;
1754 f_init();
1755
1756 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1757 vc_conn.done;
1758
1759 f_cleanup();
1760}
1761
Harald Welte7462a592020-11-23 22:07:07 +01001762/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1763private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1764{
1765 var RoutingAreaIdentification unknown_ra := {
1766 lai := {
1767 mcc_mnc := '567F99'H,
1768 lac := 33333
1769 },
1770 rac := 254
1771 };
1772 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1773}
1774testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1775 var BSSGP_ConnHdlr vc_conn;
1776 f_init();
1777
1778 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1779 vc_conn.done;
1780
1781 f_cleanup();
1782}
1783
Harald Welte0e188242020-11-22 21:46:48 +01001784/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1785private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1786{
1787 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1788}
1789testcase TC_paging_cs_sig_bvci() runs on test_CT {
1790 var BSSGP_ConnHdlr vc_conn;
1791 f_init();
1792
1793 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1794 vc_conn.done;
1795
1796 f_cleanup();
1797}
1798
Harald Welte7462a592020-11-23 22:07:07 +01001799/* CS-PAGING on SIG-BVC for unknown BVCI */
1800private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1801{
1802 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1803}
1804testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1805 var BSSGP_ConnHdlr vc_conn;
1806 f_init();
1807
1808 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1809 vc_conn.done;
1810
1811 f_cleanup();
1812}
1813
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001814private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1815 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1816 var integer i;
1817 for (i := 0; i < 10; i := i+1) {
1818 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1819 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1820 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1821
1822 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1823
1824 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1825 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1826 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1827
1828 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1829 }
1830 setverdict(pass);
1831}
1832testcase TC_flush_ll() runs on test_CT
1833{
1834 var BSSGP_ConnHdlr vc_conn;
1835 f_init();
1836
1837 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1838 vc_conn.done;
1839 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1840
1841 f_cleanup();
1842}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001843
Harald Weltef8e5c5d2020-11-27 22:37:23 +01001844private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1845runs on GlobalTest_CT {
1846[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
1847 if (ro_integer_contains(roi, pcu_idx)) {
1848 setverdict(fail, "Received multiple on same SIG BVC");
1849 }
1850 roi := roi & { pcu_idx };
1851 repeat;
1852 }
1853}
1854/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
1855testcase TC_trace() runs on GlobalTest_CT
1856{
1857 var BSSGP_ConnHdlr vc_conn;
1858 f_init();
1859 f_global_init();
1860
1861 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1862 var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
1863
1864 var ro_default defaults := {};
1865 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1866 activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
1867 }
1868 G_SGSN[0].send(pdu_tx);
1869 f_sleep(2.0);
1870 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1871 deactivate(defaults[i]);
1872 }
1873
1874 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
1875 if (not ro_integer_contains(g_roi, i)) {
1876 setverdict(fail, "Failed to receive TRACE on PCU index ", i);
1877 }
1878 }
1879 setverdict(pass);
1880
1881 f_cleanup();
1882}
1883
Harald Welte239aa502020-11-24 23:14:20 +01001884private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1885{
1886 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1887 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1888 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1889
1890 SGSN_MGMT.clear;
1891 PCU_MGMT.clear;
1892
1893 /* block the PTP BVC from the PCU side */
1894 PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
1895 /* expect state on both PCU and SGSN side to change */
1896 interleave {
1897 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
1898 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
1899 }
1900 setverdict(pass);
1901}
1902testcase TC_bvc_block_ptp() runs on test_CT
1903{
1904 f_init();
1905 f_sleep(1.0);
1906 f_block_ptp_bvc_from_pcu(0, 0);
1907 f_cleanup();
1908}
1909
1910private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1911{
1912 var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1913 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1914 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1915
1916 SGSN_MGMT.clear;
1917 PCU_MGMT.clear;
1918
1919 /* block the PTP BVC from the PCU side */
1920 PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
1921 /* expect state on both PCU and SGSN side to change */
1922 interleave {
1923 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
1924 [] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
1925 }
1926 setverdict(pass);
1927}
1928testcase TC_bvc_unblock_ptp() runs on test_CT
1929{
1930 f_init();
1931 f_sleep(1.0);
1932 f_block_ptp_bvc_from_pcu(0, 0);
1933 f_sleep(1.0);
1934 f_unblock_ptp_bvc_from_pcu(0, 0);
1935 f_cleanup();
1936}
1937
Harald Welte60a8ec72020-11-25 17:12:53 +01001938private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
1939[] pt.receive(BssgpStatusIndication:?) { repeat; }
1940}
1941private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
1942 for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
1943 if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
1944 return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
1945 }
1946 }
1947 return null;
1948}
1949private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
1950{
1951 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
1952 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
1953 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
1954 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
1955 var default d;
1956
1957 SGSN_MGMT.clear;
1958 PCU_MGMT.clear;
1959
1960 /* block the PTP BVC from the PCU side */
1961 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
1962 /* expect state on both PCU and SGSN side to change */
1963 d := activate(as_ignore_status(SGSN_MGMT));
1964 interleave {
1965 [] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
1966 [] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
1967 }
1968 deactivate(d);
1969 setverdict(pass);
1970}
1971/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
1972testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
1973{
1974 f_init();
1975 f_sleep(3.0);
1976 f_reset_ptp_bvc_from_pcu(0, 0);
1977 f_cleanup();
1978}
1979
Harald Welte16786e92020-11-27 19:11:56 +01001980private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
1981runs on test_CT {
1982 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
1983 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
1984 roi := roi & { bvci };
1985 }
1986}
1987/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
1988testcase TC_bvc_reset_sig_from_bss() runs on test_CT {
1989
1990 f_init();
1991 f_sleep(3.0);
1992
1993 /* Start BVC-RESET procedure for BVCI=0 */
1994 PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;
1995
1996 /* Activate altsteps: One for each PTP BVC within that PCUs NSE */
1997 var ro_default defaults := {};
1998 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
1999 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2000 var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
2001 defaults := defaults & { d };
2002 }
2003
2004 timer T := 3.0;
2005 T.start;
2006 alt {
2007 [] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
2008 setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
2009 }
2010 [] T.timeout;
2011 }
2012
2013 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2014 deactivate(defaults[i]);
2015 }
2016
2017 /* check if BVC-block was received on all expected BVC */
2018 for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
2019 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
2020 if (not ro_integer_contains(g_roi, bvcc.bvci)) {
2021 setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
2022 }
2023 }
2024
2025 /* check if BVC-block was not received on any unexpected BVC is not required as
2026 * such a message would basically run into 'no matching clause' */
2027
2028 f_cleanup();
2029}
2030
Harald Welte60a8ec72020-11-25 17:12:53 +01002031private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
2032{
2033 var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
2034 var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
2035 var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
2036 var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
2037 var default d;
2038
2039 SGSN_MGMT.clear;
2040 PCU_MGMT.clear;
2041
2042 /* block the PTP BVC from the PCU side */
2043 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
2044 /* expect state on both PCU and SGSN side to change */
2045 d := activate(as_ignore_status(PCU_MGMT));
2046 interleave {
2047 [] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
2048 [] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
2049 }
2050 deactivate(d);
2051 setverdict(pass);
2052}
2053/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
2054testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
2055{
2056 f_init();
2057 f_sleep(3.0);
2058 f_reset_ptp_bvc_from_sgsn(0, 0);
2059 f_cleanup();
2060}
2061
Harald Welte16786e92020-11-27 19:11:56 +01002062private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
2063runs on test_CT {
2064 var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
2065 [] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
2066 roi := roi & { nsei };
2067 }
2068}
2069/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
2070testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {
2071
2072 f_init();
2073 f_sleep(3.0);
2074
2075 /* Start BVC-RESET procedure for BVCI=0 */
2076 SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;
2077
2078 /* Activate altsteps: One for each PCU NSE */
2079 var ro_default defaults := {};
2080 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2081 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2082 var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
2083 defaults := defaults & { d };
2084 }
2085
2086 f_sleep(3.0);
2087
2088 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
2089 deactivate(defaults[i]);
2090 }
2091
2092 /* check if BVC-block was received on all expected BVC */
2093 for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
2094 var NSConfiguration nscfg := mp_nsconfig_pcu[i];
2095 if (not ro_integer_contains(g_roi, nscfg.nsei)) {
2096 setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
2097 }
2098 }
2099
2100 /* check if BVC-block was not received on any unexpected BVC is not required as
2101 * such a message would basically run into 'no matching clause' */
2102
2103 f_cleanup();
2104}
2105
Daniel Willmann423d8f42020-09-08 18:58:22 +02002106control {
2107 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01002108 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01002109 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01002110 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01002111 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01002112 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01002113 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01002114 execute( TC_resume() );
Harald Weltef8e5c5d2020-11-27 22:37:23 +01002115 execute( TC_trace() );
Harald Welte239aa502020-11-24 23:14:20 +01002116 execute( TC_bvc_block_ptp() );
2117 execute( TC_bvc_unblock_ptp() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002118 execute( TC_bvc_reset_ptp_from_bss() );
Harald Welte16786e92020-11-27 19:11:56 +01002119 execute( TC_bvc_reset_sig_from_bss() );
Harald Welte60a8ec72020-11-25 17:12:53 +01002120 execute( TC_bvc_reset_ptp_from_sgsn() );
Harald Welte16786e92020-11-27 19:11:56 +01002121 execute( TC_bvc_reset_sig_from_sgsn() );
Harald Weltef8ef0282020-11-18 12:16:59 +01002122 if (false) {
2123 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
2124 execute( TC_load_sharing_dl() );
2125 }
Harald Welte0e188242020-11-22 21:46:48 +01002126
2127 /* PAGING-PS over PTP BVC */
2128 execute( TC_paging_ps_ptp_bss() );
2129 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002130 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002131 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002132 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002133 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002134 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002135
2136 /* PAGING-PS over SIG BVC */
2137 execute( TC_paging_ps_sig_bss() );
2138 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002139 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002140 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002141 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002142 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002143 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002144
2145 /* PAGING-CS over PTP BVC */
2146 execute( TC_paging_cs_ptp_bss() );
2147 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002148 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002149 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002150 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002151 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002152 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002153
2154 /* PAGING-CS over SIG BVC */
2155 execute( TC_paging_cs_sig_bss() );
2156 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01002157 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002158 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01002159 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002160 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01002161 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01002162
2163
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01002164 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02002165}
2166
2167
2168}