blob: 0bafaa075ecab38217ab3eb63f2976780bc3e3ad [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 }
387 [] SGSN_MGMT.receive {
388 setverdict(fail, "Received unexpected message on SGSN_MGMT");
389 mtc.stop;
390 }
391
392 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
393 repeat;
394 }
395 [] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
396 repeat;
397 }
398 [] PCU_MGMT.receive(BssgpResetIndication:{0}) {
399 repeat;
400 }
401 [] PCU_MGMT.receive {
402 setverdict(fail, "Received unexpected message on PCU_MGMT");
403 mtc.stop;
404 }
405
406 [] T.timeout {
407 setverdict(fail, "Timeout waiting for unblock of all BVCs");
408 mtc.stop;
409 }
410 }
411
412 /* iterate over list and check all BVCI */
413 for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
414 var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
415 if (not ro_integer_contains(bvci_unblocked, bvci)) {
416 setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
417 mtc.stop;
418 }
419 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200420}
421
422function f_cleanup() runs on test_CT {
423 self.stop;
424}
425
426type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
427
428/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Harald Welte6d63f742020-11-15 19:44:04 +0100429function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200430 float t_guard := 30.0)
431runs on test_CT return BSSGP_ConnHdlr {
432 var BSSGP_ConnHdlr vc_conn;
433
434 var BSSGP_ConnHdlrPars pars := {
435 imei := f_gen_imei(imsi_suffix),
436 imsi := f_gen_imsi(imsi_suffix),
437 msisdn := f_gen_msisdn(imsi_suffix),
438 p_tmsi := omit,
439 p_tmsi_sig := omit,
440 tlli := f_gprs_tlli_random(),
441 tlli_old := omit,
442 ra := omit,
Harald Welte16357a92020-11-17 18:20:00 +0100443 pcu := g_pcu,
Harald Welte3dd21b32020-11-17 19:21:00 +0100444 sgsn := g_sgsn,
Daniel Willmann423d8f42020-09-08 18:58:22 +0200445 t_guard := t_guard
446 };
447
448 vc_conn := BSSGP_ConnHdlr.create(id);
Daniel Willmann423d8f42020-09-08 18:58:22 +0200449
450 vc_conn.start(f_handler_init(fn, id, pars));
451 return vc_conn;
452}
453
Harald Welte3dd21b32020-11-17 19:21:00 +0100454/* 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 +0100455private function f_connect_to_pcu_bvc(integer port_idx, integer nse_idx, integer bvc_idx)
456runs on BSSGP_ConnHdlr {
457 var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
Harald Welte3dd21b32020-11-17 19:21:00 +0100458 if (PCU[port_idx].checkstate("Connected")) {
459 /* unregister + disconnect from old BVC */
460 f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
461 disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
462 disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
463 disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
464 }
465 /* connect to new BVC and register us */
466 connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
467 connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
468 connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
469 f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
470 pcu_ct[port_idx] := bvc_ct;
Harald Welte0e188242020-11-22 21:46:48 +0100471 pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
Harald Welte3dd21b32020-11-17 19:21:00 +0100472}
473
474/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
475private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
476 if (SGSN[port_idx].checkstate("Connected")) {
477 /* unregister + disconnect from old BVC */
478 f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
479 disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
480 disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
481 disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
482 }
483 /* connect to new BVC and register us */
484 connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
485 connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
486 connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
487 f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
488 sgsn_ct[port_idx] := bvc_ct;
489}
490
Daniel Willmann423d8f42020-09-08 18:58:22 +0200491private altstep as_Tguard() runs on BSSGP_ConnHdlr {
492 [] g_Tguard.timeout {
493 setverdict(fail, "Tguard timeout");
494 mtc.stop;
495 }
496}
497
498/* first function called in every ConnHdlr */
499private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
500runs on BSSGP_ConnHdlr {
Harald Welte1e834f32020-11-15 20:02:59 +0100501 var integer i;
Daniel Willmann423d8f42020-09-08 18:58:22 +0200502 /* do some common stuff like setting up g_pars */
503 g_pars := pars;
504
505 llc := f_llc_create(false);
506
Harald Welte3dd21b32020-11-17 19:21:00 +0100507 /* default connections on PCU side: First BVC of each NSE/PCU */
508 for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
Harald Welte0e188242020-11-22 21:46:48 +0100509 f_connect_to_pcu_bvc(port_idx := i, nse_idx := i, bvc_idx := 0);
Harald Welte1e834f32020-11-15 20:02:59 +0100510 }
Harald Welte3dd21b32020-11-17 19:21:00 +0100511
512 /* default connections on SGSN side: First BVC of each NSE/SGSN */
513 for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
514 f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
Harald Welte1e834f32020-11-15 20:02:59 +0100515 }
Daniel Willmann423d8f42020-09-08 18:58:22 +0200516
517 g_Tguard.start(pars.t_guard);
518 activate(as_Tguard());
519
520 /* call the user-supplied test case function */
521 fn.apply(id);
522}
523
Harald Welte1e834f32020-11-15 20:02:59 +0100524private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
525runs on BSSGP_ConnHdlr {
526 PT.call(BSSGP_register_client:{imsi, tlli}) {
527 [] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
528 }
529}
530
531private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
532runs on BSSGP_ConnHdlr {
533 PT.call(BSSGP_unregister_client:{imsi}) {
534 [] PT.getreply(BSSGP_unregister_client:{imsi}) {};
535 }
536}
537
Harald Welte22ef5d92020-11-16 13:35:14 +0100538/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
539friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100540 integer pcu_idx := 0, integer sgsn_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100541 var PDU_BSSGP rx;
542 timer T := 1.0;
543
Daniel Willmann4798fd72020-11-24 16:23:29 +0100544 if (use_sig) {
545 PCU_SIG[pcu_idx].send(tx);
546 } else {
547 PCU[pcu_idx].send(tx);
548 }
549
Harald Welte22ef5d92020-11-16 13:35:14 +0100550 T.start;
551 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100552 [use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
553 setverdict(pass);
554 }
555 [not use_sig] SGSN[sgsn_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100556 setverdict(pass);
557 }
558 [] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
559 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
560 mtc.stop;
561 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100562 [] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
563 setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
564 mtc.stop;
565 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100566 [] T.timeout {
567 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
568 mtc.stop;
569 }
570 }
571}
572
573/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
574friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
Daniel Willmann4798fd72020-11-24 16:23:29 +0100575 integer sgsn_idx:= 0, integer pcu_idx := 0, boolean use_sig := false) runs on BSSGP_ConnHdlr {
Harald Welte22ef5d92020-11-16 13:35:14 +0100576 var PDU_BSSGP rx;
577 timer T := 1.0;
578
Daniel Willmann4798fd72020-11-24 16:23:29 +0100579 if (use_sig) {
580 SGSN_SIG[sgsn_idx].send(tx);
581 } else {
582 SGSN[sgsn_idx].send(tx);
583 }
584
Harald Welte22ef5d92020-11-16 13:35:14 +0100585 T.start;
586 alt {
Daniel Willmann4798fd72020-11-24 16:23:29 +0100587 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
588 setverdict(pass);
589 }
590 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
Harald Welte22ef5d92020-11-16 13:35:14 +0100591 setverdict(pass);
592 }
593 [] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
594 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
595 mtc.stop;
596 }
Daniel Willmann4798fd72020-11-24 16:23:29 +0100597 [] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
598 setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
599 mtc.stop;
600 }
Harald Welte22ef5d92020-11-16 13:35:14 +0100601 [] T.timeout {
602 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
603 mtc.stop;
604 }
605 }
606}
Harald Welte1e834f32020-11-15 20:02:59 +0100607
Harald Welte3807ed12020-11-24 19:05:22 +0100608/***********************************************************************
609 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
610 ***********************************************************************/
611
612type component GlobalTest_CT extends test_CT {
613 port BSSGP_PT G_PCU[NUM_PCU];
614 port BSSGP_PT G_SGSN[NUM_SGSN];
615};
616
617private function f_global_init() runs on GlobalTest_CT {
618 var integer i;
619 for (i := 0; i < lengthof(g_sgsn); i := i+1) {
620 connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
621 }
622 for (i := 0; i < lengthof(g_pcu); i := i+1) {
623 connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
624 }
625}
626
627/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
628friend function f_global_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
629 integer pcu_idx := 0, integer sgsn_idx := 0) runs on GlobalTest_CT {
630 var PDU_BSSGP rx;
631 timer T := 1.0;
632
633 G_PCU[pcu_idx].send(tx);
634 T.start;
635 alt {
636 [] G_SGSN[sgsn_idx].receive(exp_rx) {
637 setverdict(pass);
638 }
639 [] G_SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
640 setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
641 mtc.stop;
642 }
643 [] T.timeout {
644 setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
645 mtc.stop;
646 }
647 }
648}
649
650/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
651friend function f_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
652 integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
653 var PDU_BSSGP rx;
654 timer T := 1.0;
655
656 G_SGSN[sgsn_idx].send(tx);
657 T.start;
658 alt {
659 [] G_PCU[pcu_idx].receive(exp_rx) {
660 setverdict(pass);
661 }
662 [] G_PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
663 setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
664 mtc.stop;
665 }
666 [] T.timeout {
667 setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
668 mtc.stop;
669 }
670 }
671}
672
673
Daniel Willmann423d8f42020-09-08 18:58:22 +0200674/* TODO:
675 * Detach without Attach
676 * SM procedures without attach / RAU
677 * ATTACH / RAU
678 ** with / without authentication
679 ** with / without P-TMSI allocation
680 * re-transmissions of LLC frames
681 * PDP Context activation
682 ** with different GGSN config in SGSN VTY
683 ** with different PDP context type (v4/v6/v46)
684 ** timeout from GGSN
685 ** multiple / secondary PDP context
686 */
687
688private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
689 f_sleep(5.0);
690 setverdict(pass);
691}
692
693testcase TC_BVC_bringup() runs on test_CT {
694 var BSSGP_ConnHdlr vc_conn;
695 f_init();
696
697 vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
698 vc_conn.done;
699
700 f_cleanup();
701}
702
703friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
Harald Welte16357a92020-11-17 18:20:00 +0100704 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200705 timer T := 5.0;
706 var PDU_BSSGP rx_pdu;
Harald Welte16357a92020-11-17 18:20:00 +0100707 PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
Daniel Willmann423d8f42020-09-08 18:58:22 +0200708 T.start;
709 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100710 [] 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 +0200711 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
712 }
Harald Welte16357a92020-11-17 18:20:00 +0100713 [] 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 +0200714 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
715 mtc.stop;
716 }
717 [] T.timeout {
718 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
719 mtc.stop;
720 }
721 }
722 return '00'O;
723}
724
725friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100726 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Daniel Willmann423d8f42020-09-08 18:58:22 +0200727 timer T := 5.0;
Harald Welte16357a92020-11-17 18:20:00 +0100728 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 +0200729 T.start;
730 alt {
Harald Welte16357a92020-11-17 18:20:00 +0100731 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
732 [] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
Daniel Willmann423d8f42020-09-08 18:58:22 +0200733 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
734 mtc.stop;
735 }
736 [] T.timeout {
737 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
738 mtc.stop;
739 }
740 }
741}
742
743
Harald Welte92686012020-11-15 21:45:49 +0100744/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
745private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte16357a92020-11-17 18:20:00 +0100746 var integer ran_idx := 0;
747 var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
Harald Welte92686012020-11-15 21:45:49 +0100748 var integer i;
749
750 for (i := 0; i < 1024; i := i+1) {
751 var octetstring payload := f_rnd_octstring(i);
Harald Welte16357a92020-11-17 18:20:00 +0100752 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 +0100753 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte16357a92020-11-17 18:20:00 +0100754 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 +0100755
Harald Welte22ef5d92020-11-16 13:35:14 +0100756 f_pcu2sgsn(pdu_tx, pdu_rx);
Harald Welte92686012020-11-15 21:45:49 +0100757 }
758 setverdict(pass);
759}
760
761testcase TC_ul_unitdata() runs on test_CT
762{
763 var BSSGP_ConnHdlr vc_conn;
764 f_init();
765
766 vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
767 vc_conn.done;
768 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
769
770 f_cleanup();
771}
772
Harald Welte78d8db92020-11-15 23:27:27 +0100773/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
774private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
775 var integer i;
776
777 for (i := 0; i < 1024; i := i+1) {
778 var octetstring payload := f_rnd_octstring(i);
779 var template (value) PDU_BSSGP pdu_tx :=
780 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
781 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
782 var template (present) PDU_BSSGP pdu_rx :=
783 tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));
784
Harald Welte22ef5d92020-11-16 13:35:14 +0100785 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte78d8db92020-11-15 23:27:27 +0100786 }
787 setverdict(pass);
788}
789
790testcase TC_dl_unitdata() runs on test_CT
791{
792 var BSSGP_ConnHdlr vc_conn;
793 f_init();
794
795 vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
796 vc_conn.done;
797 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
798
799 f_cleanup();
800}
Harald Welte92686012020-11-15 21:45:49 +0100801
Harald Welte6dc2ac42020-11-16 09:16:17 +0100802private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
803 var integer i;
804
805 for (i := 0; i < 10; i := i+1) {
806 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
807 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
808 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })
809
Harald Welte22ef5d92020-11-16 13:35:14 +0100810 f_sgsn2pcu(pdu_tx, pdu_rx);
Harald Welte6dc2ac42020-11-16 09:16:17 +0100811 }
812 setverdict(pass);
813}
814testcase TC_ra_capability() runs on test_CT
815{
816 var BSSGP_ConnHdlr vc_conn;
817 f_init();
818
819 vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
820 vc_conn.done;
821 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
822
823 f_cleanup();
824}
825
Daniel Willmannace3ece2020-11-16 19:53:26 +0100826private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
827 var integer i;
828 var OCT1 tag;
829 for (i := 0; i < 10; i := i+1) {
830 tag := int2oct(23 + i, 1);
831 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
832 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
833 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)
834
835 f_pcu2sgsn(pdu_tx, pdu_rx);
836
837 pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
838 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
839 pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)
840
841 f_sgsn2pcu(pdu_tx, pdu_rx);
842 }
843 setverdict(pass);
844}
845testcase TC_ra_capability_upd() runs on test_CT
846{
847 var BSSGP_ConnHdlr vc_conn;
848 f_init();
849
Daniel Willmann54833f22020-11-19 15:43:52 +0100850 vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 4);
Daniel Willmannace3ece2020-11-16 19:53:26 +0100851 vc_conn.done;
852 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
853
854 f_cleanup();
855}
856
Daniel Willmann165d6612020-11-19 14:27:29 +0100857private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
858 var integer i;
859 var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
860 for (i := 0; i < 10; i := i+1) {
861 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
862 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
863 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)
864
865 f_pcu2sgsn(pdu_tx, pdu_rx);
866 }
867 setverdict(pass);
868}
869testcase TC_radio_status() runs on test_CT
870{
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
873
Daniel Willmann54833f22020-11-19 15:43:52 +0100874 vc_conn := f_start_handler(refers(f_TC_radio_status), testcasename(), g_pcu, g_sgsn, 5);
Daniel Willmann165d6612020-11-19 14:27:29 +0100875 vc_conn.done;
876 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
877
878 f_cleanup();
879}
880
Harald Welte3807ed12020-11-24 19:05:22 +0100881private function f_TC_suspend() runs on GlobalTest_CT {
Daniel Willmannfa67f492020-11-19 15:48:05 +0100882 var integer i;
Daniel Willmann165d6612020-11-19 14:27:29 +0100883
Daniel Willmannfa67f492020-11-19 15:48:05 +0100884 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100885 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmannfa67f492020-11-19 15:48:05 +0100886 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100887 var OCT4 tlli := f_gprs_tlli_random();
888 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100889 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100890 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100891
Harald Welte3807ed12020-11-24 19:05:22 +0100892 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100893
Harald Welte3807ed12020-11-24 19:05:22 +0100894 pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100895 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100896 pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
Daniel Willmannfa67f492020-11-19 15:48:05 +0100897
Harald Welte3807ed12020-11-24 19:05:22 +0100898 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmannfa67f492020-11-19 15:48:05 +0100899
900 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100901 pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
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_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
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 setverdict(pass);
908}
Harald Welte3807ed12020-11-24 19:05:22 +0100909testcase TC_suspend() runs on GlobalTest_CT
Daniel Willmannfa67f492020-11-19 15:48:05 +0100910{
Daniel Willmannfa67f492020-11-19 15:48:05 +0100911 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100912 f_global_init();
913 f_TC_suspend();
Daniel Willmannfa67f492020-11-19 15:48:05 +0100914 f_cleanup();
915}
Harald Welte6dc2ac42020-11-16 09:16:17 +0100916
Harald Welte3807ed12020-11-24 19:05:22 +0100917private function f_TC_resume() runs on GlobalTest_CT {
Daniel Willmann087a33d2020-11-19 15:58:43 +0100918 var integer i;
919
920 /* TODO: Generate RA ID for each ConnHdlr */
Harald Welte3807ed12020-11-24 19:05:22 +0100921 var RoutingAreaIdentification ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
Daniel Willmann087a33d2020-11-19 15:58:43 +0100922 for (i := 0; i < 10; i := i+1) {
Harald Welte3807ed12020-11-24 19:05:22 +0100923 var OCT4 tlli := f_gprs_tlli_random();
924 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100925 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100926 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
Daniel Willmann087a33d2020-11-19 15:58:43 +0100927
Harald Welte3807ed12020-11-24 19:05:22 +0100928 f_global_pcu2sgsn(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100929
Harald Welte3807ed12020-11-24 19:05:22 +0100930 pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100931 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
Harald Welte3807ed12020-11-24 19:05:22 +0100932 pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100933
Harald Welte3807ed12020-11-24 19:05:22 +0100934 f_global_sgsn2pcu(pdu_tx, pdu_rx);
Daniel Willmann087a33d2020-11-19 15:58:43 +0100935
936 /* These messages are simple passed through so just also test sending NACK */
Harald Welte3807ed12020-11-24 19:05:22 +0100937 pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
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_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
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 setverdict(pass);
944}
Harald Welte3807ed12020-11-24 19:05:22 +0100945testcase TC_resume() runs on GlobalTest_CT
Daniel Willmann087a33d2020-11-19 15:58:43 +0100946{
Daniel Willmann087a33d2020-11-19 15:58:43 +0100947 f_init();
Harald Welte3807ed12020-11-24 19:05:22 +0100948 f_global_init();
949 f_TC_resume();
Daniel Willmann087a33d2020-11-19 15:58:43 +0100950 f_cleanup();
951}
952
Harald Weltef8ef0282020-11-18 12:16:59 +0100953/* test the load-sharing between multiple NS-VC on the BSS side */
954private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
955 var integer i;
956
957 for (i := 0; i < 10; i := i+1) {
958 var octetstring payload := f_rnd_octstring(i);
959 var template (value) PDU_BSSGP pdu_tx :=
960 ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
961 SGSN[0].send(pdu_tx);
962 }
963 setverdict(pass);
964}
965testcase TC_load_sharing_dl() runs on test_CT_NS
966{
967 const integer num_ue := 10;
968 var BSSGP_ConnHdlr vc_conn[num_ue];
969 f_init();
970
971 /* all BVC are now fully brought up. We disconnect BSSGP from NS on the BSS
972 * side so we get the raw NsUnitdataIndication and hence observe different
973 * NSVCI */
974 disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
975 connect(g_pcu[0].vc_NS:NS_SP, self:NS);
976
977 /* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
978 * of the NS-VC is ALIVE/UNBLOCKED */
979 f_sleep(3.0);
980
981 /* start parallel components generating DL-UNITDATA from the SGSN side */
982 for (var integer i:= 0; i < num_ue; i := i+1) {
983 vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
984 }
985
986 /* now start counting all the messages that were queued before */
987 /* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
988 var ro_integer rx_count := { 0, 0, 0, 0 };
989 timer T := 2.0;
990 T.start;
991 alt {
992 [] as_NsUdiCount(0, rx_count);
993 [] as_NsUdiCount(1, rx_count);
994 [] as_NsUdiCount(2, rx_count);
995 [] as_NsUdiCount(3, rx_count);
996 [] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
997 [] NS.receive(NsStatusIndication:?) { repeat; }
998 [] NS.receive {
999 setverdict(fail, "Rx unexpected NS");
1000 mtc.stop;
1001 }
1002 [] T.timeout {
1003 }
1004 }
1005 for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
1006 log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
1007 if (rx_count[i] == 0) {
1008 setverdict(fail, "Data not shared over all NSVC");
1009 }
1010 }
1011 setverdict(pass);
1012}
1013private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
1014 var NsUnitdataIndication udi;
1015 var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
1016 [] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
1017 roi[nsvc_idx] := roi[nsvc_idx] + 1;
1018 repeat;
1019 }
1020}
1021type component test_CT_NS extends test_CT {
1022 port NS_PT NS;
1023};
1024
1025
Harald Welte0e188242020-11-22 21:46:48 +01001026/***********************************************************************
1027 * PAGING PS procedure
1028 ***********************************************************************/
1029
1030private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1031 boolean use_sig := false)
1032runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1033 var template (value) PDU_BSSGP pdu_tx;
1034 var template (present) PDU_BSSGP pdu_rx;
1035 /* we always specify '0' as BVCI in the templates below, as we override it with
1036 * 'p4' later anyway */
1037 pdu_rx := tr_BSSGP_PS_PAGING(0);
1038 pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1039 if (ispresent(g_pars.p_tmsi)) {
1040 pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1041 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1042 } else {
1043 pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
1044 pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
1045 }
1046 pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1047 pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
1048 if (use_sig == false) {
1049 SGSN[sgsn_idx].send(pdu_tx);
1050 } else {
1051 SGSN_SIG[sgsn_idx].send(pdu_tx);
1052 }
1053 return pdu_rx;
1054}
1055
1056/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1057 * specified PCU index */
1058private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1059 boolean use_sig := false,integer pcu_idx := 0)
1060runs on BSSGP_ConnHdlr {
1061 var template (present) PDU_BSSGP exp_rx;
1062 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1063 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1064 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1065 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1066 timer T := 2.0;
1067 T.start;
1068 alt {
1069 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1070 setverdict(pass);
1071 repeat;
1072 }
1073 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1074 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1075 }
1076 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1077 setverdict(pass);
1078 repeat;
1079 }
1080 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1081 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1082 }
1083 [] any from PCU.receive(exp_rx) {
1084 setverdict(fail, "Paging received on unexpected BVC");
1085 }
1086 [] any from PCU_SIG.receive(exp_rx) {
1087 setverdict(fail, "Paging received on unexpected BVC");
1088 }
1089 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1090 setverdict(fail, "Different Paging than expected received PTP BVC");
1091 }
1092 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1093 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1094 }
1095 [] T.timeout;
1096 }
1097}
1098
Harald Welte7462a592020-11-23 22:07:07 +01001099/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1100private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1101 boolean use_sig := false)
1102runs on BSSGP_ConnHdlr {
1103 var template (present) PDU_BSSGP exp_rx;
1104 exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
1105 /* Expect paging to propagate to no BSS */
1106 timer T := 2.0;
1107 T.start;
1108 alt {
1109 [] any from PCU.receive(exp_rx) {
1110 setverdict(fail, "Paging received on unexpected BVC");
1111 }
1112 [] any from PCU_SIG.receive(exp_rx) {
1113 setverdict(fail, "Paging received on unexpected BVC");
1114 }
1115 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1116 setverdict(fail, "Different Paging received on PTP BVC");
1117 }
1118 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1119 setverdict(fail, "Different Paging received on SIGNALING BVC");
1120 }
1121 [] T.timeout {
1122 setverdict(pass);
1123 }
1124 }
1125}
1126
Harald Welte0e188242020-11-22 21:46:48 +01001127private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1128{
1129 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1130 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1131 f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1132}
1133testcase TC_paging_ps_ptp_bss() runs on test_CT {
1134 var BSSGP_ConnHdlr vc_conn;
1135 f_init();
1136
1137 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
1138 vc_conn.done;
1139
1140 f_cleanup();
1141}
1142
1143/* PS-PAGING on PTP-BVC for Location Area */
1144private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1145{
1146 var template (present) PDU_BSSGP exp_rx;
1147 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1148 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1149 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1150}
1151testcase TC_paging_ps_ptp_lac() runs on test_CT {
1152 var BSSGP_ConnHdlr vc_conn;
1153 f_init();
1154
1155 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
1156 vc_conn.done;
1157
1158 f_cleanup();
1159}
1160
Harald Welte7462a592020-11-23 22:07:07 +01001161/* PS-PAGING on PTP-BVC for unknown Location Area */
1162private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1163{
1164 var GSM_Types.LocationAreaIdentification unknown_la := {
1165 mcc_mnc := '567F99'H,
1166 lac := 33333
1167 };
1168 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1169 f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1170}
1171testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
1172 var BSSGP_ConnHdlr vc_conn;
1173 f_init();
1174
1175 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1176 vc_conn.done;
1177
1178 f_cleanup();
1179}
1180
Harald Welte0e188242020-11-22 21:46:48 +01001181/* PS-PAGING on PTP-BVC for Routeing Area */
1182private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1183{
1184 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1185 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1186 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1187}
1188testcase TC_paging_ps_ptp_rac() runs on test_CT {
1189 var BSSGP_ConnHdlr vc_conn;
1190 f_init();
1191
1192 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
1193 vc_conn.done;
1194
1195 f_cleanup();
1196}
1197
Harald Welte7462a592020-11-23 22:07:07 +01001198/* PS-PAGING on PTP-BVC for unknown Routeing Area */
1199private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1200{
1201 var RoutingAreaIdentification unknown_ra := {
1202 lai := {
1203 mcc_mnc := '567F99'H,
1204 lac := 33333
1205 },
1206 rac := 254
1207 };
1208 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1209 f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1210}
1211testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
1212 var BSSGP_ConnHdlr vc_conn;
1213 f_init();
1214
1215 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1216 vc_conn.done;
1217
1218 f_cleanup();
1219}
1220
Harald Welte0e188242020-11-22 21:46:48 +01001221/* PS-PAGING on PTP-BVC for BVCI (one cell) */
1222private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1223{
1224 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1225 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1226}
1227testcase TC_paging_ps_ptp_bvci() runs on test_CT {
1228 var BSSGP_ConnHdlr vc_conn;
1229 f_init();
1230
1231 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
1232 vc_conn.done;
1233
1234 f_cleanup();
1235}
1236
Harald Welte7462a592020-11-23 22:07:07 +01001237/* PS-PAGING on PTP-BVC for unknown BVCI */
1238private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1239{
1240 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1241 f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1242}
1243testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
1244 var BSSGP_ConnHdlr vc_conn;
1245 f_init();
1246
1247 vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1248 vc_conn.done;
1249
1250 f_cleanup();
1251}
1252
Harald Welte0e188242020-11-22 21:46:48 +01001253/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
1254private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
1255runs on BSSGP_ConnHdlr {
1256[] PCU_SIG[pcu_idx].receive(exp_rx) {
1257 if (ro_integer_contains(roi, pcu_idx)) {
1258 setverdict(fail, "Received multiple paging on same SIG BVC");
1259 }
1260 roi := roi & { pcu_idx };
1261 repeat;
1262 }
1263[] PCU[pcu_idx].receive(exp_rx) {
1264 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1265 }
1266[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1267 setverdict(fail, "Different Paging than expected received SIGNALING BVC");
1268 }
1269[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
1270 setverdict(fail, "Different Paging than expected received PTP BVC");
1271 }
1272}
1273
1274type record of default ro_default;
1275
1276/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1277private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1278 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1279{
1280 var template (present) PDU_BSSGP exp_rx;
1281 exp_rx := f_send_paging_ps(p4, 0, true);
1282
1283 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1284 var ro_default defaults := {};
1285 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1286 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1287 defaults := defaults & { d };
1288 }
1289 f_sleep(2.0);
1290 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1291 deactivate(defaults[i]);
1292 }
1293 log("Paging received on PCU ", g_roi);
1294
1295 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1296 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1297 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1298 if (exp_on_i and not rx_on_i) {
1299 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1300 }
1301 if (not exp_on_i and rx_on_i) {
1302 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1303 }
1304 }
1305 setverdict(pass);
1306}
1307
1308/* PS-PAGING on SIG-BVC for BSS Area */
1309private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1310{
1311 /* we expect the paging to arrive on all three NSE */
1312 f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1313}
1314testcase TC_paging_ps_sig_bss() runs on test_CT {
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
1317
1318 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1319 vc_conn.done;
1320
1321 f_cleanup();
1322}
1323
1324/* PS-PAGING on SIG-BVC for Location Area */
1325private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1326{
1327 /* Both PCU index 0 and 1 have a BVC within the LAC */
1328 f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1329}
1330testcase TC_paging_ps_sig_lac() runs on test_CT {
1331 var BSSGP_ConnHdlr vc_conn;
1332 f_init();
1333
1334 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1335 vc_conn.done;
1336
1337 f_cleanup();
1338}
1339
Harald Welte7462a592020-11-23 22:07:07 +01001340/* PS-PAGING on SIG-BVC for unknown Location Area */
1341private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1342{
1343 var GSM_Types.LocationAreaIdentification unknown_la := {
1344 mcc_mnc := '567F99'H,
1345 lac := 33333
1346 };
1347 f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1348}
1349testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
1350 var BSSGP_ConnHdlr vc_conn;
1351 f_init();
1352
1353 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1354 vc_conn.done;
1355
1356 f_cleanup();
1357}
1358
Harald Welte0e188242020-11-22 21:46:48 +01001359/* PS-PAGING on SIG-BVC for Routeing Area */
1360private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1361{
1362 /* Only PCU index 0 has a matching BVC within the LAC */
1363 f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1364}
1365testcase TC_paging_ps_sig_rac() runs on test_CT {
1366 var BSSGP_ConnHdlr vc_conn;
1367 f_init();
1368
1369 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1370 vc_conn.done;
1371
1372 f_cleanup();
1373}
1374
Harald Welte7462a592020-11-23 22:07:07 +01001375/* PS-PAGING on SIG-BVC for unknown Routeing Area */
1376private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1377{
1378 var RoutingAreaIdentification unknown_ra := {
1379 lai := {
1380 mcc_mnc := '567F99'H,
1381 lac := 33333
1382 },
1383 rac := 254
1384 };
1385 f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1386}
1387testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
1388 var BSSGP_ConnHdlr vc_conn;
1389 f_init();
1390
1391 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1392 vc_conn.done;
1393
1394 f_cleanup();
1395}
1396
Harald Welte0e188242020-11-22 21:46:48 +01001397/* PS-PAGING on SIG-BVC for BVCI (one cell) */
1398private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1399{
1400 f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1401}
1402testcase TC_paging_ps_sig_bvci() runs on test_CT {
1403 var BSSGP_ConnHdlr vc_conn;
1404 f_init();
1405
1406 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1407 vc_conn.done;
1408
1409 f_cleanup();
1410}
1411
Harald Welte7462a592020-11-23 22:07:07 +01001412/* PS-PAGING on SIG-BVC for unknown BVCI */
1413private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1414{
1415 f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1416}
1417testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
1418 var BSSGP_ConnHdlr vc_conn;
1419 f_init();
1420
1421 vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1422 vc_conn.done;
1423
1424 f_cleanup();
1425}
1426
1427
Harald Welte0e188242020-11-22 21:46:48 +01001428
1429/***********************************************************************
1430 * PAGING CS procedure
1431 ***********************************************************************/
1432
1433private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1434 boolean use_sig := false)
1435runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
1436 var template (value) PDU_BSSGP pdu_tx;
1437 var template (present) PDU_BSSGP pdu_rx;
1438 /* we always specify '0' as BVCI in the templates below, as we override it with
1439 * 'p4' later anyway */
1440 pdu_rx := tr_BSSGP_CS_PAGING(0);
1441 pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
1442 if (ispresent(g_pars.p_tmsi)) {
1443 pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
1444 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
1445 } else {
1446 pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
1447 pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
1448 }
1449 pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1450 pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
1451 if (use_sig == false) {
1452 SGSN[sgsn_idx].send(pdu_tx);
1453 } else {
1454 SGSN_SIG[sgsn_idx].send(pdu_tx);
1455 }
1456 return pdu_rx;
1457}
1458
1459/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
1460 * specified PCU index */
1461private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1462 boolean use_sig := false,integer pcu_idx := 0)
1463runs on BSSGP_ConnHdlr {
1464 var template (present) PDU_BSSGP exp_rx;
1465 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1466 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1467 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1468 /* Expect paging to propagate to the one BSS addressed by the BVCI only */
1469 timer T := 2.0;
1470 T.start;
1471 alt {
1472 [not use_sig] PCU[pcu_idx].receive(exp_rx) {
1473 setverdict(pass);
1474 repeat;
1475 }
1476 [not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1477 setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
1478 }
1479 [use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
1480 setverdict(pass);
1481 repeat;
1482 }
1483 [use_sig] PCU[pcu_idx].receive(exp_rx) {
1484 setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
1485 }
1486 [] any from PCU.receive(exp_rx) {
1487 setverdict(fail, "Paging received on unexpected BVC");
1488 }
1489 [] any from PCU_SIG.receive(exp_rx) {
1490 setverdict(fail, "Paging received on unexpected BVC");
1491 }
1492 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1493 setverdict(fail, "Different Paging than expected received PTP BVC");
1494 }
1495 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1496 setverdict(fail, "Different Paging than expected on SIGNALING BVC");
1497 }
1498 [] T.timeout;
1499 }
1500}
1501
Harald Welte7462a592020-11-23 22:07:07 +01001502/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
1503private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1504 boolean use_sig := false)
1505runs on BSSGP_ConnHdlr {
1506 var template (present) PDU_BSSGP exp_rx;
1507 exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
1508 /* Expect paging to propagate to no BSS */
1509 timer T := 2.0;
1510 T.start;
1511 alt {
1512 [] any from PCU.receive(exp_rx) {
1513 setverdict(fail, "Paging received on unexpected BVC");
1514 }
1515 [] any from PCU_SIG.receive(exp_rx) {
1516 setverdict(fail, "Paging received on unexpected BVC");
1517 }
1518 [] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1519 setverdict(fail, "Different Paging received on PTP BVC");
1520 }
1521 [] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
1522 setverdict(fail, "Different Paging received on SIGNALING BVC");
1523 }
1524 [] T.timeout {
1525 setverdict(pass);
1526 }
1527 }
1528}
1529
Harald Welte0e188242020-11-22 21:46:48 +01001530private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
1531{
1532 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1533 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1534 f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
1535}
1536testcase TC_paging_cs_ptp_bss() runs on test_CT {
1537 var BSSGP_ConnHdlr vc_conn;
1538 f_init();
1539
1540 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
1541 vc_conn.done;
1542
1543 f_cleanup();
1544}
1545
1546/* CS-PAGING on PTP-BVC for Location Area */
1547private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
1548{
1549 var template (present) PDU_BSSGP exp_rx;
1550 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1551 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1552 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
1553}
1554testcase TC_paging_cs_ptp_lac() runs on test_CT {
1555 var BSSGP_ConnHdlr vc_conn;
1556 f_init();
1557
1558 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
1559 vc_conn.done;
1560
1561 f_cleanup();
1562}
1563
Harald Welte7462a592020-11-23 22:07:07 +01001564/* CS-PAGING on PTP-BVC for unknown Location Area */
1565private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1566{
1567 var GSM_Types.LocationAreaIdentification unknown_la := {
1568 mcc_mnc := '567F99'H,
1569 lac := 33333
1570 };
1571 /* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
1572 f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
1573}
1574testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
1575 var BSSGP_ConnHdlr vc_conn;
1576 f_init();
1577
1578 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1579 vc_conn.done;
1580
1581 f_cleanup();
1582}
1583
Harald Welte0e188242020-11-22 21:46:48 +01001584/* CS-PAGING on PTP-BVC for Routeing Area */
1585private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
1586{
1587 /* doesn't really make sense: Sending to a single BVCI means the message ends up
1588 * at that BVC (cell) only, and paging all over the BSS area is not possible */
1589 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
1590}
1591testcase TC_paging_cs_ptp_rac() runs on test_CT {
1592 var BSSGP_ConnHdlr vc_conn;
1593 f_init();
1594
1595 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
1596 vc_conn.done;
1597
1598 f_cleanup();
1599}
1600
Harald Welte7462a592020-11-23 22:07:07 +01001601/* CS-PAGING on PTP-BVC for unknown Routeing Area */
1602private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1603{
1604 var RoutingAreaIdentification unknown_ra := {
1605 lai := {
1606 mcc_mnc := '567F99'H,
1607 lac := 33333
1608 },
1609 rac := 254
1610 };
1611 /* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
1612 f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
1613}
1614testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
1615 var BSSGP_ConnHdlr vc_conn;
1616 f_init();
1617
1618 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1619 vc_conn.done;
1620
1621 f_cleanup();
1622}
1623
Harald Welte0e188242020-11-22 21:46:48 +01001624/* CS-PAGING on PTP-BVC for BVCI (one cell) */
1625private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
1626{
1627 /* this should be the normal case for MS in READY MM state after a lower layer failure */
1628 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
1629}
1630testcase TC_paging_cs_ptp_bvci() runs on test_CT {
1631 var BSSGP_ConnHdlr vc_conn;
1632 f_init();
1633
1634 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
1635 vc_conn.done;
1636
1637 f_cleanup();
1638}
1639
Harald Welte7462a592020-11-23 22:07:07 +01001640/* CS-PAGING on PTP-BVC for unknown BVCI */
1641private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1642{
1643 /* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
1644 f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
1645}
1646testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
1647 var BSSGP_ConnHdlr vc_conn;
1648 f_init();
1649
1650 vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1651 vc_conn.done;
1652
1653 f_cleanup();
1654}
1655
Harald Welte0e188242020-11-22 21:46:48 +01001656/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
1657private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
1658 ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
1659{
1660 var template (present) PDU_BSSGP exp_rx;
1661 exp_rx := f_send_paging_cs(p4, 0, true);
1662
1663 /* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
1664 var ro_default defaults := {};
1665 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1666 var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
1667 defaults := defaults & { d };
1668 }
1669 f_sleep(2.0);
1670 for (var integer i := 0; i < lengthof(defaults); i := i+1) {
1671 deactivate(defaults[i]);
1672 }
1673 log("Paging received on PCU ", g_roi);
1674
1675 for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
1676 var boolean rx_on_i := ro_integer_contains(g_roi, i);
1677 var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
1678 if (exp_on_i and not rx_on_i) {
1679 setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
1680 }
1681 if (not exp_on_i and rx_on_i) {
1682 setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
1683 }
1684 }
1685 setverdict(pass);
1686}
1687
1688/* CS-PAGING on SIG-BVC for BSS Area */
1689private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
1690{
1691 /* we expect the paging to arrive on all three NSE */
1692 f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
1693}
1694testcase TC_paging_cs_sig_bss() runs on test_CT {
1695 var BSSGP_ConnHdlr vc_conn;
1696 f_init();
1697
1698 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
1699 vc_conn.done;
1700
1701 f_cleanup();
1702}
1703
1704/* CS-PAGING on SIG-BVC for Location Area */
1705private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
1706{
1707 /* Both PCU index 0 and 1 have a BVC within the LAC */
1708 f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1});
1709}
1710testcase TC_paging_cs_sig_lac() runs on test_CT {
1711 var BSSGP_ConnHdlr vc_conn;
1712 f_init();
1713
1714 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
1715 vc_conn.done;
1716
1717 f_cleanup();
1718}
1719
Harald Welte7462a592020-11-23 22:07:07 +01001720/* CS-PAGING on SIG-BVC for unknown Location Area */
1721private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
1722{
1723 var GSM_Types.LocationAreaIdentification unknown_la := {
1724 mcc_mnc := '567F99'H,
1725 lac := 33333
1726 };
1727 f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
1728}
1729testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
1730 var BSSGP_ConnHdlr vc_conn;
1731 f_init();
1732
1733 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1734 vc_conn.done;
1735
1736 f_cleanup();
1737}
1738
Harald Welte0e188242020-11-22 21:46:48 +01001739/* CS-PAGING on SIG-BVC for Routeing Area */
1740private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
1741{
1742 /* Only PCU index 0 has a matching BVC within the LAC */
1743 f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
1744}
1745testcase TC_paging_cs_sig_rac() runs on test_CT {
1746 var BSSGP_ConnHdlr vc_conn;
1747 f_init();
1748
1749 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
1750 vc_conn.done;
1751
1752 f_cleanup();
1753}
1754
Harald Welte7462a592020-11-23 22:07:07 +01001755/* CS-PAGING on SIG-BVC for unknown Routeing Area */
1756private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
1757{
1758 var RoutingAreaIdentification unknown_ra := {
1759 lai := {
1760 mcc_mnc := '567F99'H,
1761 lac := 33333
1762 },
1763 rac := 254
1764 };
1765 f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
1766}
1767testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
1768 var BSSGP_ConnHdlr vc_conn;
1769 f_init();
1770
1771 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
1772 vc_conn.done;
1773
1774 f_cleanup();
1775}
1776
Harald Welte0e188242020-11-22 21:46:48 +01001777/* CS-PAGING on SIG-BVC for BVCI (one cell) */
1778private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
1779{
1780 f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
1781}
1782testcase TC_paging_cs_sig_bvci() runs on test_CT {
1783 var BSSGP_ConnHdlr vc_conn;
1784 f_init();
1785
1786 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
1787 vc_conn.done;
1788
1789 f_cleanup();
1790}
1791
Harald Welte7462a592020-11-23 22:07:07 +01001792/* CS-PAGING on SIG-BVC for unknown BVCI */
1793private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
1794{
1795 f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
1796}
1797testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
1798 var BSSGP_ConnHdlr vc_conn;
1799 f_init();
1800
1801 vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
1802 vc_conn.done;
1803
1804 f_cleanup();
1805}
1806
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001807private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
1808 var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
1809 var integer i;
1810 for (i := 0; i < 10; i := i+1) {
1811 var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1812 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1813 var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
1814
1815 f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);
1816
1817 pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1818 /* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
1819 pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
1820
1821 f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
1822 }
1823 setverdict(pass);
1824}
1825testcase TC_flush_ll() runs on test_CT
1826{
1827 var BSSGP_ConnHdlr vc_conn;
1828 f_init();
1829
1830 vc_conn := f_start_handler(refers(f_TC_flush_ll), testcasename(), g_pcu, g_sgsn, 6);
1831 vc_conn.done;
1832 /* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */
1833
1834 f_cleanup();
1835}
Harald Welte6dc2ac42020-11-16 09:16:17 +01001836
Daniel Willmann423d8f42020-09-08 18:58:22 +02001837control {
1838 execute( TC_BVC_bringup() );
Harald Welte92686012020-11-15 21:45:49 +01001839 execute( TC_ul_unitdata() );
Harald Welte78d8db92020-11-15 23:27:27 +01001840 execute( TC_dl_unitdata() );
Harald Welte6dc2ac42020-11-16 09:16:17 +01001841 execute( TC_ra_capability() );
Daniel Willmannace3ece2020-11-16 19:53:26 +01001842 execute( TC_ra_capability_upd() );
Daniel Willmann165d6612020-11-19 14:27:29 +01001843 execute( TC_radio_status() );
Daniel Willmannfa67f492020-11-19 15:48:05 +01001844 execute( TC_suspend() );
Daniel Willmann087a33d2020-11-19 15:58:43 +01001845 execute( TC_resume() );
Harald Weltef8ef0282020-11-18 12:16:59 +01001846 if (false) {
1847 /* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
1848 execute( TC_load_sharing_dl() );
1849 }
Harald Welte0e188242020-11-22 21:46:48 +01001850
1851 /* PAGING-PS over PTP BVC */
1852 execute( TC_paging_ps_ptp_bss() );
1853 execute( TC_paging_ps_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001854 execute( TC_paging_ps_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001855 execute( TC_paging_ps_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001856 execute( TC_paging_ps_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001857 execute( TC_paging_ps_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01001858 execute( TC_paging_ps_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001859
1860 /* PAGING-PS over SIG BVC */
1861 execute( TC_paging_ps_sig_bss() );
1862 execute( TC_paging_ps_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001863 execute( TC_paging_ps_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001864 execute( TC_paging_ps_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001865 execute( TC_paging_ps_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001866 execute( TC_paging_ps_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01001867 execute( TC_paging_ps_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001868
1869 /* PAGING-CS over PTP BVC */
1870 execute( TC_paging_cs_ptp_bss() );
1871 execute( TC_paging_cs_ptp_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001872 execute( TC_paging_cs_ptp_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001873 execute( TC_paging_cs_ptp_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001874 execute( TC_paging_cs_ptp_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001875 execute( TC_paging_cs_ptp_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01001876 execute( TC_paging_cs_ptp_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001877
1878 /* PAGING-CS over SIG BVC */
1879 execute( TC_paging_cs_sig_bss() );
1880 execute( TC_paging_cs_sig_lac() );
Harald Welte7462a592020-11-23 22:07:07 +01001881 execute( TC_paging_cs_sig_lac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001882 execute( TC_paging_cs_sig_rac() );
Harald Welte7462a592020-11-23 22:07:07 +01001883 execute( TC_paging_cs_sig_rac_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001884 execute( TC_paging_cs_sig_bvci() );
Harald Welte7462a592020-11-23 22:07:07 +01001885 execute( TC_paging_cs_sig_bvci_unknown() );
Harald Welte0e188242020-11-22 21:46:48 +01001886
1887
Daniel Willmann91a8e25b2020-11-24 14:50:59 +01001888 execute( TC_flush_ll() );
Daniel Willmann423d8f42020-09-08 18:58:22 +02001889}
1890
1891
1892}