blob: 4e3514456edbb9e5bf59cb6c6f19cf15940f4997 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010074 handle_sns := false,
75 nsvc := {
76 {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 21010,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010083 remote_ip := "127.0.0.1",
84 data_weight := 1,
85 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010086 }
87 },
88 nsvci := 97
89 }
90 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020091 },
92 {
Harald Welte5e514fa2018-07-05 00:01:45 +020093 nsei := 97,
94 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010095 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
101 local_udp_port := 21011,
102 local_ip := "127.0.0.1",
103 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100104 remote_ip := "127.0.0.1",
105 data_weight := 1,
106 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100107 }
108 },
109 nsvci := 98
110 }
111 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200112 },
113 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200114 nsei := 98,
115 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100116 handle_sns := false,
117 nsvc := {
118 {
119 provider := {
120 ip := {
121 address_family := AF_INET,
122 local_udp_port := 21012,
123 local_ip := "127.0.0.1",
124 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100125 remote_ip := "127.0.0.1",
126 data_weight := 1,
127 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100128 }
129 },
130 nsvci := 99
131 }
132 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200133 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200134 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200135
136 RAN_Configurations mp_ranap_cfg := {
137 {
138 transport := RANAP_TRANSPORT_IuCS,
139 sccp_service_type := "mtp3_itu",
140 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
141 own_pc := 195,
142 own_ssn := 142,
143 peer_pc := 188, /* 0.23.4 */
144 peer_ssn := 142,
145 sio := '83'O,
146 rctx := 2
147 }
148 }
Harald Welte5ac31492018-02-15 20:39:13 +0100149};
150
Harald Welte5339b2e2020-10-04 22:52:56 +0200151const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100152type record GbInstance {
153 NS_CT vc_NS,
154 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200155 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100156 BssgpConfig cfg
157};
Harald Welte96a33b02018-02-04 10:36:22 +0100158
Harald Welte2fa771f2019-05-02 20:13:53 +0200159const integer NUM_GB := 3;
160type record length(NUM_GB) of GbInstance GbInstances;
161type record length(NUM_GB) of NSConfiguration NSConfigurations;
162type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200163
Harald Welte26fbb6e2019-04-14 17:32:46 +0200164const integer NUM_RNC := 1;
165type record of RAN_Configuration RAN_Configurations;
166
Harald Welte96a33b02018-02-04 10:36:22 +0100167type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200168 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200169 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200170 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100171
Harald Welte5ac31492018-02-15 20:39:13 +0100172 var GSUP_Emulation_CT vc_GSUP;
173 var IPA_Emulation_CT vc_GSUP_IPA;
174 /* only to get events from IPA underneath GSUP */
175 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100176
Harald Welte5339b2e2020-10-04 22:52:56 +0200177 /* only needed at start to get the per-BVC references */
178 port BSSGP_CT_PROC_PT PROC;
179
Philipp Maier7df55e02020-12-14 23:46:04 +0100180 /* used by RIM related test */
181 port BSSGP_PT RIM[NUM_GB];
182
Harald Welteeded9ad2018-02-17 20:57:34 +0100183 var GTP_Emulation_CT vc_GTP;
184
Harald Weltebd194722018-02-16 22:11:08 +0100185 port TELNETasp_PT SGSNVTY;
186
Harald Welte96a33b02018-02-04 10:36:22 +0100187 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200188 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100189};
190
Harald Welte26fbb6e2019-04-14 17:32:46 +0200191type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100192 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100193 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200194 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100195}
196
197type record SGSN_ConnHdlrNetworkPars {
198 boolean expect_ptmsi,
199 boolean expect_auth,
200 boolean expect_ciph
201};
202
203type record BSSGP_ConnHdlrPars {
204 /* IMEI of the simulated ME */
205 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200206 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100207 hexstring imsi,
208 /* MSISDN of the simulated MS (probably unused) */
209 hexstring msisdn,
210 /* P-TMSI allocated to the simulated MS */
211 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100212 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100213 /* TLLI of the simulated MS */
214 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100215 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100216 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200217 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200218 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
219 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100220 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100221 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200222 float t_guard,
223 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200224 SCCP_PAR_Address sccp_addr_local optional,
225 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100226};
227
Alexander Couzens89508702018-07-31 04:16:10 +0200228private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200229 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200230 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
231
232 var RoutingAreaIdentificationV ret := {
233 mccDigit1 := mcc_mnc[0],
234 mccDigit2 := mcc_mnc[1],
235 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200236 mncDigit3 := mcc_mnc[3],
237 mncDigit1 := mcc_mnc[4],
238 mncDigit2 := mcc_mnc[5],
Pau Espin Pedroldeaaa902021-02-12 18:41:04 +0100239 lac := int2oct(cell_id.ra_id.lai.lac, 2),
240 rac := int2oct(cell_id.ra_id.rac, 1)
Alexander Couzens89508702018-07-31 04:16:10 +0200241 }
242 return ret;
243};
244
Alexander Couzens51114d12018-07-31 18:41:56 +0200245private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
246 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
247 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100248 /* connect lower end of BSSGP emulation with NS upper port */
249 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100250
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200251 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200252 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
253 /* resolve the per-BVC component references */
254 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
255 connect(self:PROC, gb.vc_BSSGP:PROC);
256 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
257 disconnect(self:PROC, gb.vc_BSSGP:PROC);
258 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100259 /* connect RIM related port */
260 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100261}
262
263private function f_init_gsup(charstring id) runs on test_CT {
264 id := id & "-GSUP";
265 var GsupOps ops := {
266 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
267 };
268
269 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
270 vc_GSUP := GSUP_Emulation_CT.create(id);
271
272 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
273 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
274 /* we use this hack to get events like ASP_IPA_EVENT_UP */
275 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
276
277 vc_GSUP.start(GSUP_Emulation.main(ops, id));
278 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
279
280 /* wait for incoming connection to GSUP port before proceeding */
281 timer T := 10.0;
282 T.start;
283 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700284 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100285 [] T.timeout {
286 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200287 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100288 }
289 }
290}
291
Harald Welteeded9ad2018-02-17 20:57:34 +0100292private function f_init_gtp(charstring id) runs on test_CT {
293 id := id & "-GTP";
294
295 var GtpEmulationCfg gtp_cfg := {
296 gtpc_bind_ip := mp_ggsn_ip,
297 gtpc_bind_port := GTP1C_PORT,
298 gtpu_bind_ip := mp_ggsn_ip,
299 gtpu_bind_port := GTP1U_PORT,
300 sgsn_role := false
301 };
302
303 vc_GTP := GTP_Emulation_CT.create(id);
304 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
305}
306
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200307friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100308 map(self:SGSNVTY, system:SGSNVTY);
309 f_vty_set_prompts(SGSNVTY);
310 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200311 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100312 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
313}
314
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200315private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
316 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200317 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200318 } else {
319 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
320 }
321}
322
Harald Weltebd194722018-02-16 22:11:08 +0100323
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200324/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
325function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200326 var integer i;
327
Harald Welte96a33b02018-02-04 10:36:22 +0100328 if (g_initialized == true) {
329 return;
330 }
331 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100332 g_gb[0].cfg := {
333 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200334 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200335 bvc := {
336 {
337 bvci := 196,
338 cell_id := {
339 ra_id := {
340 lai := {
341 mcc_mnc := mcc_mnc,
342 lac := 13135
343 },
344 rac := 0
345 },
346 cell_id := 20960
347 },
Harald Welte4d112c92020-11-12 19:48:31 +0100348 depth := BSSGP_DECODE_DEPTH_L3,
349 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200350 }
351 }
Harald Welte5ac31492018-02-15 20:39:13 +0100352 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200353 g_gb[1].cfg := {
354 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200355 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200356 bvc := {
357 {
358 bvci := 210,
359 cell_id := {
360 ra_id := {
361 lai := {
362 mcc_mnc := mcc_mnc,
363 lac := 13200
364 },
365 rac := 0
366 },
367 cell_id := 20961
368 },
Harald Welte4d112c92020-11-12 19:48:31 +0100369 depth := BSSGP_DECODE_DEPTH_L3,
370 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200371 }
372 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200373 };
374 g_gb[2].cfg := {
375 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200376 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200377 bvc := {
378 {
379 bvci := 220,
380 cell_id := {
381 ra_id := {
382 lai := {
383 mcc_mnc := mcc_mnc,
384 lac := 13300
385 },
386 rac := 0
387 },
388 cell_id := 20962
389 },
Harald Welte4d112c92020-11-12 19:48:31 +0100390 depth := BSSGP_DECODE_DEPTH_L3,
391 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200392 }
393 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200394 };
Harald Welte96a33b02018-02-04 10:36:22 +0100395
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200396 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200397 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
398 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
399 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200400
Alexander Couzens1552e792019-07-23 20:38:39 +0200401 if (g_ranap_enable) {
402 for (i := 0; i < NUM_RNC; i := i+1) {
403 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
404 f_ran_adapter_start(g_ranap[i]);
405 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200406 }
Harald Welte5ac31492018-02-15 20:39:13 +0100407 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100408 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200409 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100410}
Harald Welte96a33b02018-02-04 10:36:22 +0100411
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200412function f_cleanup() runs on test_CT {
413 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200414 if (g_ranap_enable) {
415 for (i := 0; i < NUM_RNC; i := i+1) {
416 f_ran_adapter_cleanup(g_ranap[i]);
417 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200418 }
419 self.stop;
420}
421
Harald Welte26fbb6e2019-04-14 17:32:46 +0200422private function RncUnitdataCallback(RANAP_PDU ranap)
423runs on RAN_Emulation_CT return template RANAP_PDU {
424 var template RANAP_PDU resp := omit;
425
426 log ("RANAP_RncUnitDataCallback");
427 /* answer all RESET with RESET ACK */
428 if (match(ranap, tr_RANAP_Reset)) {
429 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
430 var CN_DomainIndicator dom;
431 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
432 resp := ts_RANAP_ResetAck(dom);
433 }
434 return resp;
435}
436
437const RanOps RNC_RanOps := {
438 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
439 ranap_unitdata_cb := refers(RncUnitdataCallback),
440 ps_domain := true,
441 decode_dtap := true,
442 role_ms := true,
443 protocol := RAN_PROTOCOL_RANAP,
444 transport := RANAP_TRANSPORT_IuCS,
445 use_osmux := false,
446 sccp_addr_local := omit,
447 sccp_addr_peer := omit
448};
449
Harald Welte5ac31492018-02-15 20:39:13 +0100450type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
451
452/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200453function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100454 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100455runs on test_CT return BSSGP_ConnHdlr {
456 var BSSGP_ConnHdlr vc_conn;
457 var SGSN_ConnHdlrNetworkPars net_pars := {
458 expect_ptmsi := true,
459 expect_auth := true,
460 expect_ciph := false
461 };
462 var BSSGP_ConnHdlrPars pars := {
463 imei := f_gen_imei(imsi_suffix),
464 imsi := f_gen_imsi(imsi_suffix),
465 msisdn := f_gen_msisdn(imsi_suffix),
466 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100467 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100468 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100469 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100470 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200471 bssgp_cell_id := {
472 gb[0].cfg.bvc[0].cell_id,
473 gb[1].cfg.bvc[0].cell_id,
474 gb[2].cfg.bvc[0].cell_id
475 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200476 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100477 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100478 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200479 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200480 sccp_addr_local := omit,
481 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100482 };
483
Alexander Couzens1552e792019-07-23 20:38:39 +0200484 if (g_ranap_enable) {
485 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
486 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
487 }
488
Harald Welte5ac31492018-02-15 20:39:13 +0100489 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200490
491 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
492 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
493 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100494 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200495
496 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
497 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
498 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100499 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200500
501 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
502 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
503 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100504 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100505
Harald Welte26fbb6e2019-04-14 17:32:46 +0200506 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200507 if (g_ranap_enable) {
508 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
509 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
510 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200511
Harald Welte5ac31492018-02-15 20:39:13 +0100512 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
513 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
514
Harald Welteeded9ad2018-02-17 20:57:34 +0100515 connect(vc_conn:GTP, vc_GTP:CLIENT);
516 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
517
Harald Welte5ac31492018-02-15 20:39:13 +0100518 vc_conn.start(f_handler_init(fn, id, pars));
519 return vc_conn;
520}
521
Harald Welte62e29582018-02-16 21:17:11 +0100522private altstep as_Tguard() runs on BSSGP_ConnHdlr {
523 [] g_Tguard.timeout {
524 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200525 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100526 }
527}
528
Harald Welte5ac31492018-02-15 20:39:13 +0100529/* first function called in every ConnHdlr */
530private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
531runs on BSSGP_ConnHdlr {
532 /* do some common stuff like setting up g_pars */
533 g_pars := pars;
534
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200535 llc := f_llc_create(false);
536
Harald Welte5ac31492018-02-15 20:39:13 +0100537 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200538 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100539 /* tell GSUP dispatcher to send this IMSI to us */
540 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100541 /* tell GTP dispatcher to send this IMSI to us */
542 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100543
Harald Welte62e29582018-02-16 21:17:11 +0100544 g_Tguard.start(pars.t_guard);
545 activate(as_Tguard());
546
Harald Welte5ac31492018-02-15 20:39:13 +0100547 /* call the user-supplied test case function */
548 fn.apply(id);
549 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100550}
551
552/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100553 * Detach without Attach
554 * SM procedures without attach / RAU
555 * ATTACH / RAU
556 ** with / without authentication
557 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100558 * re-transmissions of LLC frames
559 * PDP Context activation
560 ** with different GGSN config in SGSN VTY
561 ** with different PDP context type (v4/v6/v46)
562 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100563 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100564 */
565
566testcase TC_wait_ns_up() runs on test_CT {
567 f_init();
568 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200569 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100570}
571
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572friend function is_gb(integer ran_index) return boolean {
573 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200574}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200575friend function is_iu(integer ran_index) return boolean {
576 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200577}
578
Alexander Couzens0507ec32019-09-15 22:41:22 +0200579function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200580 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200581 BSSGP[ran_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[ran_index], llc_enc));
Harald Weltea05b8072019-04-23 22:35:05 +0200582}
583
Alexander Couzens0507ec32019-09-15 22:41:22 +0200584private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200585 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
586 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
587 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200588 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200589}
590
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200591/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
592function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
593 log("Sending InitialUE: ", l3_mo);
594 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
595 var RANAP_PDU ranap;
596 var LAI lai := {
597 pLMNidentity := '62F224'O,
598 lAC := '1234'O,
599 iE_Extensions := omit
600 };
601 var SAI sai := {
602 pLMNidentity := lai.pLMNidentity,
603 lAC := lai.lAC,
604 sAC := '0000'O, /* FIXME */
605 iE_Extensions := omit
606 };
607 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
608 var GlobalRNC_ID grnc_id := {
609 pLMNidentity := lai.pLMNidentity,
610 rNC_ID := 2342 /* FIXME */
611 };
612
613 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
614 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
615 alt {
616 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
617 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
618 setverdict(fail, "DISC.ind from SCCP");
619 mtc.stop;
620 }
621 }
622}
623
624/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200625function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
626 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200627 if (g_pars.rnc_send_initial_ue) {
628 g_pars.rnc_send_initial_ue := false;
629 f_send_l3_initial_ue(l3_mo);
630 } else {
631 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
632 }
633 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200634 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200635 }
636}
637
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200638altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700639 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200640 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100641 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200642 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100643 repeat;
644 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200645 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200646 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200647 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200648 repeat;
649 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200650 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100651 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200652 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200653 repeat;
654 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200655 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200656 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200657 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100658 repeat;
659 }
660}
Harald Welte96a33b02018-02-04 10:36:22 +0100661
Harald Welteca362462019-05-02 20:11:21 +0200662/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200663function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200664runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200665 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200666 var PDU_L3_SGSN_MS l3_mt;
667 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200668 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
669 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200670 l3_mt := mt.dtap;
671 }
Harald Welteca362462019-05-02 20:11:21 +0200672 }
673 return l3_mt;
674}
675
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200676/* perform GMM authentication (if expected).
677 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
678 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200679function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100680 var PDU_L3_MS_SGSN l3_mo;
681 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200682 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100683 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200684 var GSUP_IE auth_tuple;
685 var template AuthenticationParameterAUTNTLV autn;
686
687 if (umts_aka_challenge) {
688 g_pars.vec := f_gen_auth_vec_3g();
689 autn := {
690 elementIdentifier := '28'O,
691 lengthIndicator := lengthof(g_pars.vec.autn),
692 autnValue := g_pars.vec.autn
693 };
694
695 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
696 g_pars.vec.sres,
697 g_pars.vec.kc,
698 g_pars.vec.ik,
699 g_pars.vec.ck,
700 g_pars.vec.autn,
701 g_pars.vec.res));
702 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
703 } else {
704 g_pars.vec := f_gen_auth_vec_2g();
705 autn := omit;
706 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
707 g_pars.vec.sres,
708 g_pars.vec.kc));
709 log("GSUP sends only 2G auth tuple", auth_tuple);
710 }
Harald Welteca362462019-05-02 20:11:21 +0200711
Harald Welte5ac31492018-02-15 20:39:13 +0100712 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
713 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200714
715 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
716 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200717 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100718 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200719 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
720
721 if (umts_aka_challenge and not force_gsm_sres) {
722 /* set UMTS response instead */
723 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
724 valueField := substr(g_pars.vec.res, 0, 4)
725 };
726 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
727 elementIdentifier := '21'O,
728 lengthIndicator := lengthof(g_pars.vec.res) - 4,
729 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
730 };
731 }
732
733 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100734 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
735 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
736 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
737 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
738 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200739 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200740
741 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200742 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200743 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
744 key_sts := ?)) {
745 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
746 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200747 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200748 }
749 }
Harald Welte76dee092018-02-16 22:12:59 +0100750 } else {
751 /* wait for identity procedure */
752 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100753 }
Harald Welte76dee092018-02-16 22:12:59 +0100754
Harald Welte5ac31492018-02-15 20:39:13 +0100755 deactivate(di);
756}
757
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200758function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100759 g_pars.p_tmsi := p_tmsi;
760 /* update TLLI */
761 g_pars.tlli_old := g_pars.tlli;
762 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100763 if (is_gb(ran_index)) {
764 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
765 }
Harald Weltef70997d2018-02-17 10:11:19 +0100766}
767
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100768function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100769 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100770 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100771 if (not (g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100772 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100773 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200774 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100775 }
Harald Welte04683d02018-02-16 22:43:45 +0100776 g_pars.ra := aa.routingAreaIdentification;
777 if (ispresent(aa.allocatedPTMSI)) {
778 if (not g_pars.net.expect_ptmsi) {
779 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200780 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100781 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100782 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
783 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100784 }
785 if (ispresent(aa.msIdentity)) {
786 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200787 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100788 }
789 /* P-TMSI.sig */
790 if (ispresent(aa.ptmsiSignature)) {
791 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
792 }
793 /* updateTimer */
794 // aa.readyTimer
795 /* T3302, T3319, T3323, T3312_ext, T3324 */
796}
797
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200798function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100799 /* mandatory IE */
800 g_pars.ra := ra.routingAreaId;
801 if (ispresent(ra.allocatedPTMSI)) {
802 if (not g_pars.net.expect_ptmsi) {
803 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200804 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100805 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100806 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
807 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100808 }
809 if (ispresent(ra.msIdentity)) {
810 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200811 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100812 }
813 /* P-TMSI.sig */
814 if (ispresent(ra.ptmsiSignature)) {
815 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
816 }
817 /* updateTimer */
818 // aa.readyTimer
819 /* T3302, T3319, T3323, T3312_ext, T3324 */
820}
821
822
Harald Welte5a4fa042018-02-16 20:59:21 +0100823function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
824 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
825}
826
Harald Welte23178c52018-02-17 09:36:33 +0100827/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700828private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100829 if (ispresent(g_pars.p_tmsi)) {
830 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
831 } else {
832 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
833 }
834}
835
Harald Welte311ec272018-02-17 09:40:03 +0100836private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100837 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100838 /* Expect MSC to perform LU with HLR */
839 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100840 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
841 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
842 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100843 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
844 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
845}
846
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200847friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100848 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200849 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200850 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100851
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200852 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
853 * 3G auth vectors */
854 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
855 /* The thing is, if the solSACapability is 'omit', then the
856 * revisionLevelIndicatior is at the wrong place! */
857 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
858
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200859 f_send_l3(attach_req, ran_index);
860 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200861 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100862 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100863
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200864 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100865 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200866
Harald Welte04683d02018-02-16 22:43:45 +0100867 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200868 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200869
870 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200871 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200872 as_iu_release_compl_disc();
873 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200874
875 /* Race condition
876 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
877 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
878 * arrived before it. This results in a test case failure.
879 * Delay execution by 50 ms
880 */
881 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200882}
883
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200884friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
885 timer T := 5.0;
886 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100887 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200888 T.start;
889 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100890 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200891 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
892 }
Harald Welte9b461a92020-12-10 23:41:14 +0100893 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200894 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
895 mtc.stop;
896 }
897 [] T.timeout {
898 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
899 mtc.stop;
900 }
901 }
902 return '00'O;
903}
904
905friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
906 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100907 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200908 T.start;
909 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100910 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
911 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200912?)) {
913 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
914 mtc.stop;
915 }
916 [] T.timeout {
917 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
918 mtc.stop;
919 }
920 }
921}
922
923
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200924private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
925 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100926 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100927}
928
929testcase TC_attach() runs on test_CT {
930 var BSSGP_ConnHdlr vc_conn;
931 f_init();
932 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200933 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100934 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200935 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100936}
937
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100938testcase TC_attach_mnc3() runs on test_CT {
939 var BSSGP_ConnHdlr vc_conn;
940 f_init('023042'H);
941 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200942 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100943 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200944 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100945}
946
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200947private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
948 f_gmm_attach(true, false);
949 setverdict(pass);
950}
951testcase TC_attach_umts_aka_umts_res() runs on test_CT {
952 var BSSGP_ConnHdlr vc_conn;
953 f_init();
954 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200955 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200956 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200957 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200958}
959
960private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
961 f_gmm_attach(true, true);
962 setverdict(pass);
963}
964testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
965 var BSSGP_ConnHdlr vc_conn;
966 f_init();
967 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200968 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200969 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200970 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200971}
972
Harald Welte5b7c8122018-02-16 21:48:17 +0100973/* MS never responds to ID REQ, expect ATTACH REJECT */
974private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100975 var RoutingAreaIdentificationV old_ra := f_random_RAI();
976
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200977 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100978 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200979 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100980 /* don't send ID Response */
981 repeat;
982 }
Harald Welte955aa942019-05-03 01:29:29 +0200983 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100984 setverdict(pass);
985 }
Harald Welte955aa942019-05-03 01:29:29 +0200986 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100987 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200988 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100989 }
990 }
991}
992testcase TC_attach_auth_id_timeout() runs on test_CT {
993 var BSSGP_ConnHdlr vc_conn;
994 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200995 vc_conn := f_start_handler(refers(f_TC_attach_auth_id_timeout), testcasename(), g_gb, 2, 40.0);
Harald Welte5b7c8122018-02-16 21:48:17 +0100996 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200997 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100998}
999
1000/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1001private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001002 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1003
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001004 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001005 alt {
1006 [] as_mm_identity();
1007 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1008 }
1009 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001010 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001011 setverdict(pass);
1012}
1013testcase TC_attach_auth_sai_timeout() runs on test_CT {
1014 var BSSGP_ConnHdlr vc_conn;
1015 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001016 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001017 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001018 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001019}
1020
Harald Weltefe253882018-02-17 09:25:00 +01001021/* HLR rejects SAI, expect ATTACH REJECT */
1022private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001023 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1024
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001025 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001026 alt {
1027 [] as_mm_identity();
1028 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1029 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1030 }
1031 }
Harald Welte955aa942019-05-03 01:29:29 +02001032 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001033 setverdict(pass);
1034}
1035testcase TC_attach_auth_sai_reject() runs on test_CT {
1036 var BSSGP_ConnHdlr vc_conn;
1037 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001038 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001039 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001040 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001041}
1042
Harald Welte5b7c8122018-02-16 21:48:17 +01001043/* HLR never responds to UL REQ, expect ATTACH REJECT */
1044private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001045 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001046 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1047
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001048 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001049 f_gmm_auth();
1050 /* Expect MSC to perform LU with HLR */
1051 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1052 /* Never follow-up with ISD_REQ or UL_RES */
1053 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001054 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001055 setverdict(pass);
1056 }
Harald Welte955aa942019-05-03 01:29:29 +02001057 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1058 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001059 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001060 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001061 }
1062 }
1063}
1064testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1065 var BSSGP_ConnHdlr vc_conn;
1066 f_init();
1067 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001068 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001069 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001070 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001071}
1072
Harald Welteb7c14e92018-02-17 09:29:16 +01001073/* HLR rejects UL REQ, expect ATTACH REJECT */
1074private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001075 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001076 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1077
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001078 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001079 f_gmm_auth();
1080 /* Expect MSC to perform LU with HLR */
1081 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1082 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1083 }
1084 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001085 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001086 setverdict(pass);
1087 }
Harald Welte955aa942019-05-03 01:29:29 +02001088 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1089 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001090 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001091 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001092 }
1093 }
1094}
1095testcase TC_attach_gsup_lu_reject() runs on test_CT {
1096 var BSSGP_ConnHdlr vc_conn;
1097 f_init();
1098 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001099 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001100 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001101 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001102}
1103
1104
Harald Welte3823e2e2018-02-16 21:53:48 +01001105/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1106private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001107 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001108 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1109
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001110 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001111 f_gmm_auth();
1112 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001113 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001114
Harald Welte955aa942019-05-03 01:29:29 +02001115 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1116 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001117 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001118 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001119 setverdict(pass);
1120}
Harald Welte3823e2e2018-02-16 21:53:48 +01001121testcase TC_attach_combined() runs on test_CT {
1122 var BSSGP_ConnHdlr vc_conn;
1123 f_init();
1124 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001125 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001126 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001127 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001128}
1129
Harald Welte76dee092018-02-16 22:12:59 +01001130/* Attempt of GPRS ATTACH in 'accept all' mode */
1131private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001132 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001133 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1134
1135 g_pars.net.expect_auth := false;
1136
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001137 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001138 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001139 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1140 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001141 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001142 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001143 setverdict(pass);
1144}
1145testcase TC_attach_accept_all() runs on test_CT {
1146 var BSSGP_ConnHdlr vc_conn;
1147 f_init();
1148 f_sleep(1.0);
1149 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001150 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001151 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001152 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001153}
Harald Welte5b7c8122018-02-16 21:48:17 +01001154
Harald Welteb2124b22018-02-16 22:26:56 +01001155/* Attempt of GPRS ATTACH in 'accept all' mode */
1156private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001157 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1158
1159 /* Simulate a foreign IMSI */
1160 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001161 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001162
1163 g_pars.net.expect_auth := false;
1164
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001165 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001166 alt {
1167 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001168 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001169 setverdict(pass);
1170 }
Harald Welte955aa942019-05-03 01:29:29 +02001171 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001172 setverdict(pass);
1173 }
Harald Welte955aa942019-05-03 01:29:29 +02001174 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001175 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001176 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001177 }
Harald Welteb2124b22018-02-16 22:26:56 +01001178 }
1179}
1180testcase TC_attach_closed() runs on test_CT {
1181 var BSSGP_ConnHdlr vc_conn;
1182 f_init();
1183 f_sleep(1.0);
1184 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1185 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001186 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001187 vc_conn.done;
1188 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001189 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001190 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001191 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001192}
1193
Harald Welte04683d02018-02-16 22:43:45 +01001194/* Routing Area Update from Unknown TLLI -> REJECT */
1195private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001196 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1197
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001198 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +01001199 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001200 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001201 setverdict(pass);
1202 }
1203 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001204 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001205 }
1206}
1207testcase TC_rau_unknown() runs on test_CT {
1208 var BSSGP_ConnHdlr vc_conn;
1209 f_init();
1210 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001211 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001212 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001213 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001214}
1215
Harald Welte91636de2018-02-17 10:16:14 +01001216private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001217 /* first perform regular attach */
1218 f_TC_attach(id);
1219
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001220 f_routing_area_update(g_pars.ra);
1221
Harald Welte91636de2018-02-17 10:16:14 +01001222}
1223testcase TC_attach_rau() runs on test_CT {
1224 var BSSGP_ConnHdlr vc_conn;
1225 f_init();
1226 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001227 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001228 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001229 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001230}
Harald Welte04683d02018-02-16 22:43:45 +01001231
Harald Welte6abb9fe2018-02-17 15:24:48 +01001232/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001233function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001234 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001235 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001236 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001237 if (expect_purge) {
1238 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1239 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1240 }
1241 T.start;
1242 alt {
1243 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1244 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001245 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001246 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001247 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001248 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001249 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001250 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001251 /* TODO: check if any PDP contexts are deactivated on network side? */
1252 }
1253 [power_off] T.timeout {
1254 setverdict(pass);
1255 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001256 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001257 g_pars.ra := omit;
1258 setverdict(pass);
1259 /* TODO: check if any PDP contexts are deactivated on network side? */
1260 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001261 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001262 if (power_off) {
1263 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1264 } else {
1265 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1266 }
1267 mtc.stop;
1268 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001269 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001270 }
1271}
1272
1273/* IMSI DETACH (non-power-off) for unknown TLLI */
1274private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1275 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1276}
1277testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1278 var BSSGP_ConnHdlr vc_conn;
1279 f_init();
1280 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001281 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001282 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001283 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001284}
1285
1286/* IMSI DETACH (power-off) for unknown TLLI */
1287private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1288 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1289}
1290testcase TC_detach_unknown_poweroff() runs on test_CT {
1291 var BSSGP_ConnHdlr vc_conn;
1292 f_init();
1293 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001294 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001295 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001296 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001297}
1298
1299/* IMSI DETACH (non-power-off) for known TLLI */
1300private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1301 /* first perform regular attach */
1302 f_TC_attach(id);
1303
1304 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1305}
1306testcase TC_detach_nopoweroff() runs on test_CT {
1307 var BSSGP_ConnHdlr vc_conn;
1308 f_init();
1309 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001310 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001311 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001312 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001313}
1314
1315/* IMSI DETACH (power-off) for known TLLI */
1316private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1317 /* first perform regular attach */
1318 f_TC_attach(id);
1319
1320 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1321}
1322testcase TC_detach_poweroff() runs on test_CT {
1323 var BSSGP_ConnHdlr vc_conn;
1324 f_init();
1325 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001326 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001327 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001328 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001329}
1330
Harald Welteeded9ad2018-02-17 20:57:34 +01001331type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001332 BIT3 tid, /* L3 Transaction ID */
1333 BIT4 nsapi, /* SNDCP NSAPI */
1334 BIT4 sapi, /* LLC SAPI */
1335 QoSV qos, /* QoS parameters */
1336 PDPAddressV addr, /* IP address */
1337 octetstring apn optional, /* APN name */
1338 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1339 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001340 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001341 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001342
Harald Welte822f9102018-02-18 20:39:06 +01001343 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1344 OCT4 ggsn_tei_u, /* GGSN TEI User */
1345 octetstring ggsn_ip_c, /* GGSN IP Control */
1346 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001347 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001348
Harald Welte822f9102018-02-18 20:39:06 +01001349 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1350 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1351 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1352 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001353};
1354
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001355
1356private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1357 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1358 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1359 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1360 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1361 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1362 f_gtp_register_teid(apars.ggsn_tei_c);
1363 f_gtp_register_teid(apars.ggsn_tei_u);
1364}
1365
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001366function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001367runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001368 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1369 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001370 var template Recovery_gtpc recovery := omit;
1371
1372 if (send_recovery) {
1373 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1374 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001375
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001376 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001377 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001378 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1379 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1380 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1381 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1382 apars.sgsn_tei_c, apars.gtp_resp_cause,
1383 apars.ggsn_tei_c, apars.ggsn_tei_u,
1384 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001385 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1386 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001387 }
1388 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001389 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001390 setverdict(pass);
1391 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001392 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001393 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001394 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001395 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001396 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001397 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001398 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001399 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001400 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001401 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1402 mtc.stop;
1403 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001404 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001405 setverdict(pass);
1406 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001407 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001408 }
1409}
1410
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001411function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001412runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001413 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1414 var Gtp1cUnitdata g_ud;
1415
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001416 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001417 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1418 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001419 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001420 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1421 }
1422 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001423 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001424 setverdict(pass);
1425 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001426 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001427 }
1428}
1429
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001430function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001431runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001432 var Gtp1cUnitdata g_ud;
1433 var integer seq_nr := 23;
1434 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1435
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001436 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001437 if (error_ind) {
1438 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1439 } else {
1440 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1441 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001442
1443 timer T := 5.0;
1444 T.start;
1445
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001446 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001447 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1448 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001449 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001450 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1451 repeat;
1452 }
1453 [] T.timeout {
1454 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1455 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001456 }
1457}
1458
Harald Welte6f203162018-02-18 22:04:55 +01001459
Harald Welteeded9ad2018-02-17 20:57:34 +01001460/* Table 10.5.156/3GPP TS 24.008 */
1461template (value) QoSV t_QosDefault := {
1462 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1463 delayClass := '100'B, /* best effort */
1464 spare1 := '00'B,
1465 precedenceClass := '010'B, /* normal */
1466 spare2 := '0'B,
1467 peakThroughput := '0000'B, /* subscribed */
1468 meanThroughput := '00000'B, /* subscribed */
1469 spare3 := '000'B,
1470 deliverErroneusSDU := omit,
1471 deliveryOrder := omit,
1472 trafficClass := omit,
1473 maxSDUSize := omit,
1474 maxBitrateUplink := omit,
1475 maxBitrateDownlink := omit,
1476 sduErrorRatio := omit,
1477 residualBER := omit,
1478 trafficHandlingPriority := omit,
1479 transferDelay := omit,
1480 guaranteedBitRateUplink := omit,
1481 guaranteedBitRateDownlink := omit,
1482 sourceStatisticsDescriptor := omit,
1483 signallingIndication := omit,
1484 spare4 := omit,
1485 maxBitrateDownlinkExt := omit,
1486 guaranteedBitRateDownlinkExt := omit,
1487 maxBitrateUplinkExt := omit,
1488 guaranteedBitRateUplinkExt := omit,
1489 maxBitrateDownlinkExt2 := omit,
1490 guaranteedBitRateDownlinkExt2 := omit,
1491 maxBitrateUplinkExt2 := omit,
1492 guaranteedBitRateUplinkExt2 := omit
1493}
1494
1495/* 10.5.6.4 / 3GPP TS 24.008 */
1496template (value) PDPAddressV t_AddrIPv4dyn := {
1497 pdpTypeOrg := '0001'B, /* IETF */
1498 spare := '0000'B,
1499 pdpTypeNum := '21'O, /* IPv4 */
1500 addressInfo := omit
1501}
1502template (value) PDPAddressV t_AddrIPv6dyn := {
1503 pdpTypeOrg := '0001'B, /* IETF */
1504 spare := '0000'B,
1505 pdpTypeNum := '53'O, /* IPv6 */
1506 addressInfo := omit
1507}
1508
Harald Welte37692d82018-02-18 15:21:34 +01001509template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001510 tid := '000'B,
1511 nsapi := '0101'B, /* < 5 are reserved */
1512 sapi := '0011'B, /* 3/5/9/11 */
1513 qos := t_QosDefault,
1514 addr := t_AddrIPv4dyn,
1515 apn := omit,
1516 pco := omit,
1517 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001518 gtp_resp_cause := int2oct(128, 1),
1519 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001520
1521 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001522 ggsn_tei_c := f_rnd_octstring(4),
1523 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001524 ggsn_ip_c := f_inet_addr(ggsn_ip),
1525 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001526 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001527
Harald Welteeded9ad2018-02-17 20:57:34 +01001528 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001529 sgsn_tei_u := omit,
1530 sgsn_ip_c := omit,
1531 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001532}
1533
Harald Welte37692d82018-02-18 15:21:34 +01001534template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1535 connId := 1,
1536 remName := f_inet_ntoa(ip),
1537 remPort := GTP1U_PORT
1538}
1539
1540template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1541 connId := 1,
1542 remName := f_inet_ntoa(ip),
1543 remPort := GTP1C_PORT
1544}
1545
1546private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1547 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1548 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1549}
1550
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001551private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1552 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001553 repeat;
1554 }
1555}
1556
1557template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1558 pDU_SN_UNITDATA := {
1559 nsapi := nsapi,
1560 moreBit := ?,
1561 snPduType := '1'B,
1562 firstSegmentIndicator := ?,
1563 spareBit := ?,
1564 pcomp := ?,
1565 dcomp := ?,
1566 npduNumber := ?,
1567 segmentNumber := ?,
1568 npduNumberContinued := ?,
1569 dataSegmentSnUnitdataPdu := payload
1570 }
1571}
1572
1573/* simple case: single segment, no compression */
1574template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1575 pDU_SN_UNITDATA := {
1576 nsapi := nsapi,
1577 moreBit := '0'B,
1578 snPduType := '1'B,
1579 firstSegmentIndicator := '1'B,
1580 spareBit := '0'B,
1581 pcomp := '0000'B,
1582 dcomp := '0000'B,
1583 npduNumber := '0000'B,
1584 segmentNumber := '0000'B,
1585 npduNumberContinued := '00'O,
1586 dataSegmentSnUnitdataPdu := payload
1587 }
1588}
1589
1590/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001591private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer ran_index := 0, boolean expect_fwd := true)
Harald Weltef7191672019-05-02 20:37:23 +02001592runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001593 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001594 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1595 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001596 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001597 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1598 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001599 [] as_xid(apars, ran_index);
1600 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001601 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1602 [expect_fwd] T.timeout {
1603 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1604 mtc.stop;
1605 }
1606 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1607 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1608 mtc.stop;
1609 }
1610 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001611 }
1612}
1613
Harald Welte64d6b512020-06-17 16:42:00 +02001614/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001615private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001616runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001617 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1618 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1619 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001620 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001621 /* Expect PDU via GTP from SGSN on simulated GGSN */
1622 alt {
1623 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1624 }
1625}
1626
Harald Welteeded9ad2018-02-17 20:57:34 +01001627private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001628 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001629
1630 /* first perform regular attach */
1631 f_TC_attach(id);
1632
1633 f_pdp_ctx_act(apars);
1634}
1635testcase TC_attach_pdp_act() runs on test_CT {
1636 var BSSGP_ConnHdlr vc_conn;
1637 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001638 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001639 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001640 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001641}
Harald Welteb2124b22018-02-16 22:26:56 +01001642
Harald Welte835b15f2018-02-18 14:39:11 +01001643/* PDP Context activation for not-attached subscriber; expect fail */
1644private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001645 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001646 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001647 apars.apn, apars.pco));
1648 alt {
1649 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001650 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001651 setverdict(pass);
1652 }
1653 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1654 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001655 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001656 }
Harald Welte955aa942019-05-03 01:29:29 +02001657 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001658 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001659 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001660 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001661 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001662 }
1663}
1664testcase TC_pdp_act_unattached() runs on test_CT {
1665 var BSSGP_ConnHdlr vc_conn;
1666 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001667 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001668 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001669 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001670}
1671
Harald Welte37692d82018-02-18 15:21:34 +01001672/* ATTACH + PDP CTX ACT + user plane traffic */
1673private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1674 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1675
1676 /* first perform regular attach */
1677 f_TC_attach(id);
1678 /* then activate PDP context */
1679 f_pdp_ctx_act(apars);
1680 /* then transceive a downlink PDU */
1681 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1682 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1683}
1684testcase TC_attach_pdp_act_user() runs on test_CT {
1685 var BSSGP_ConnHdlr vc_conn;
1686 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001687 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001688 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001689 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001690}
1691
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001692/* ATTACH + PDP CTX ACT; reject from GGSN */
1693private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1694 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1695
1696 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1697 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1698
1699 /* first perform regular attach */
1700 f_TC_attach(id);
1701 /* then activate PDP context */
1702 f_pdp_ctx_act(apars);
1703}
1704testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1705 var BSSGP_ConnHdlr vc_conn;
1706 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001707 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001708 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001709 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001710}
Harald Welte835b15f2018-02-18 14:39:11 +01001711
Harald Welte6f203162018-02-18 22:04:55 +01001712/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1713private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1714 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1715
1716 /* first perform regular attach */
1717 f_TC_attach(id);
1718 /* then activate PDP context */
1719 f_pdp_ctx_act(apars);
1720 /* then transceive a downlink PDU */
1721 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1722 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1723
1724 f_pdp_ctx_deact_mo(apars, '00'O);
1725}
1726testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1727 var BSSGP_ConnHdlr vc_conn;
1728 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001729 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
Harald Welte6f203162018-02-18 22:04:55 +01001730 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001731 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001732}
1733
Harald Welte57b9b7f2018-02-18 22:28:13 +01001734/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1735private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1736 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1737
1738 /* first perform regular attach */
1739 f_TC_attach(id);
1740 /* then activate PDP context */
1741 f_pdp_ctx_act(apars);
1742 /* then transceive a downlink PDU */
1743 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1744 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1745
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001746 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001747}
1748testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1749 var BSSGP_ConnHdlr vc_conn;
1750 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001751 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb, 22);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001752 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001753 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001754}
1755
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001756/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1757private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1758 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1759 var Gtp1cUnitdata g_ud;
1760 var integer i;
1761 var OCT1 cause_regular_deact := '24'O;
1762
1763 /* first perform regular attach + PDP context act */
1764 f_TC_attach(id);
1765 f_pdp_ctx_act(apars);
1766
1767 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1768 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1769
1770 for (i := 0; i < 2; i := i+1) {
1771 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1772 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1773 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1774 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1775 }
1776 }
1777
1778 alt {
1779 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1780 setverdict(pass);
1781 }
1782 [] as_xid(apars, 0);
1783 }
1784
1785 /* Make sure second DeactPdpAccept is sent: */
1786 timer T := 2.0;
1787 T.start;
1788 alt {
1789 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1790 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1791 }
1792 [] T.timeout {
1793 setverdict(pass);
1794 }
1795 }
1796
1797 setverdict(pass);
1798}
1799testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1800 var BSSGP_ConnHdlr vc_conn;
1801 f_init();
1802 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1803 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001804 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001805}
1806
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001807/* ATTACH + ATTACH (2nd) */
1808private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1809 g_pars.t_guard := 5.0;
1810
1811 /* first perform regular attach */
1812 f_TC_attach(id);
1813
1814 /* second to perform regular attach */
1815 f_TC_attach(id);
1816}
1817
1818
1819testcase TC_attach_second_attempt() runs on test_CT {
1820 var BSSGP_ConnHdlr vc_conn;
1821 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001822 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001823 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001824 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001825}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001826
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001827private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1828 var Gtp1cUnitdata g_ud;
1829 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1830 var integer seq_nr;
1831
1832 /* first perform regular attach */
1833 f_TC_attach(id);
1834 /* then activate PDP context */
1835 f_pdp_ctx_act(apars);
1836
1837 /* Wait to receive first echo request and send initial Restart counter */
1838 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1839 BSSGP[0].clear;
1840 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1841 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1842 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1843 }
1844
1845 /* At some point next echo request not answered will timeout and SGSN
1846 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1847 timer T := 3.0 * 6.0 + 16.0;
1848 T.start;
1849 alt {
1850 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1851 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1852 setverdict(pass);
1853 }
1854 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1855 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1856 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1857 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1858 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1859 repeat;
1860 }
1861 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1862 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1863 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1864 repeat;
1865 }
1866 [] T.timeout {
1867 setverdict(fail, "BSSGP DeactPdpReq not received");
1868 mtc.stop;
1869 }
1870 [] as_xid(apars);
1871 }
1872 T.stop
1873
1874 setverdict(pass);
1875}
1876/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1877testcase TC_attach_echo_timeout() runs on test_CT {
1878 var BSSGP_ConnHdlr vc_conn;
1879 g_use_echo := true;
1880 f_init();
1881 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1882 vc_conn.done;
1883 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001884 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001885}
1886
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001887private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001888 var Gtp1cUnitdata g_ud;
1889 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1890
1891 /* first perform regular attach */
1892 f_TC_attach(id);
1893 /* Activate a pdp context against the GGSN */
1894 f_pdp_ctx_act(apars);
1895 /* Wait to receive first echo request and send initial Restart counter */
1896 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1897 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1898 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1899 }
1900 /* Wait to receive second echo request and send incremented Restart
1901 counter. This will fake a restarted GGSN, and pdp ctx allocated
1902 should be released by SGSN */
1903 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1904 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1905 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1906 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1907 }
1908 var OCT1 cause_network_failure := int2oct(38, 1)
1909 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001910 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001911 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001912 setverdict(pass);
1913 }
1914 [] as_xid(apars);
1915 }
1916 setverdict(pass);
1917}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001918/* ATTACH + trigger Recovery procedure through EchoResp */
1919testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001920 var BSSGP_ConnHdlr vc_conn;
1921 g_use_echo := true
1922 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001923 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_echo), testcasename(), g_gb, 23, 30.0);
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001924 vc_conn.done;
1925 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001926 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001927}
1928
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001929private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1930 var Gtp1cUnitdata g_ud;
1931 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1932 var integer seq_nr := 23;
1933 var GtpPeer peer;
1934 /* first perform regular attach */
1935 f_TC_attach(id);
1936
1937 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1938 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1939 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1940 f_pdp_ctx_act(apars, true);
1941
1942 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1943/* received. */
1944 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1945
1946 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1947 would be great to have an active pdp context here before triggering
1948 Recovery, and making sure the the DEACT request is sent by the SGSN.
1949 */
1950
1951 /* Activate a pdp context against the GGSN, send incremented Recovery
1952 IE. This should trigger the recovery path, but still this specific
1953 CTX activation should work. */
1954 apars.exp_rej_cause := omit; /* default value for tests */
1955 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1956 f_pdp_ctx_act(apars, true);
1957
1958 setverdict(pass);
1959}
1960/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1961testcase TC_attach_restart_ctr_create() runs on test_CT {
1962 var BSSGP_ConnHdlr vc_conn;
1963 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001964 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb, 24, 30.0);
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001965 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001966 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001967}
1968
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001969/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1970private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1971 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1972 var integer seq_nr := 23;
1973 var GtpPeer peer;
1974 var integer i;
1975
1976 /* first perform regular attach */
1977 f_TC_attach(id);
1978 /* then activate PDP context */
1979 f_pdp_ctx_act(apars);
1980
Alexander Couzens0e510e62018-07-28 23:06:00 +02001981 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001982 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1983 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1984
1985 for (i := 0; i < 5; i := i+1) {
1986 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001987 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001988 [] as_xid(apars);
1989 }
1990 }
1991
1992 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1993
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001994 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001995 setverdict(pass);
1996}
1997testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1998 var BSSGP_ConnHdlr vc_conn;
1999 f_init();
2000 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002001 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_mt_t3395_expire), testcasename(), g_gb, 25, 60.0);
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002002 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002003 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002004}
2005
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002006/* ATTACH + PDP CTX ACT dropped + retrans */
2007private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2008 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2009 var Gtp1cUnitdata g_ud_first, g_ud_second;
2010 /* first perform regular attach */
2011 f_TC_attach(id);
2012
2013 /* then activate PDP context on the Gb side */
2014 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2015 apars.apn, apars.pco), 0);
2016
2017 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2018 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2019 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2020 if (g_ud_first != g_ud_second) {
2021 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2022 mtc.stop;
2023 }
2024 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2025 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2026 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2027 apars.sgsn_tei_c, apars.gtp_resp_cause,
2028 apars.ggsn_tei_c, apars.ggsn_tei_u,
2029 apars.nsapi,
2030 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2031 omit, omit));
2032 }
Harald Welte955aa942019-05-03 01:29:29 +02002033 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002034
2035 /* Now the same with Deact */
2036 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2037 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2038 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2039 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2040 if (g_ud_first != g_ud_second) {
2041 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2042 mtc.stop;
2043 }
2044 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2045 BSSGP[0].clear;
2046 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2047 }
2048 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002049 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002050 setverdict(pass);
2051 }
2052 [] as_xid(apars, 0);
2053 }
2054
2055 setverdict(pass);
2056}
2057testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2058 var BSSGP_ConnHdlr vc_conn;
2059 f_init();
2060 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2061 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002062 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002063}
2064
2065/* Test that SGSN GTP response retransmit queue works fine */
2066private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2067 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2068 var integer seq_nr := 23;
2069 var Gtp1cUnitdata g_ud_first, g_ud_second;
2070 var template Gtp1cUnitdata g_delete_req;
2071 /* first perform regular attach + PDP context act */
2072 f_TC_attach(id);
2073 f_pdp_ctx_act(apars);
2074
2075 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2076 BSSGP[0].clear;
2077 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2078 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2079 GTP.send(g_delete_req);
2080 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002081 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002082 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2083 }
2084 [] as_xid(apars, 0);
2085 }
2086 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2087 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2088 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2089 mtc.stop;
2090 }
2091 };
2092
2093 /* Send duplicate DeleteCtxReq */
2094 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2095 GTP.send(g_delete_req);
2096 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2097 if (g_ud_first != g_ud_second) {
2098 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2099 mtc.stop;
2100 }
2101 }
2102
2103 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2104 * is handled differently by SGSN (expect "non-existent" cause) */
2105 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2106 GTP.send(g_delete_req);
2107 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2108 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2109 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2110 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2111 mtc.stop;
2112 }
2113 }
2114
2115 setverdict(pass);
2116}
2117testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2118 var BSSGP_ConnHdlr vc_conn;
2119 f_init();
2120 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2121 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002122 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002123}
2124
Alexander Couzens5e307b42018-05-22 18:12:20 +02002125private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2126 /* MS: perform regular attach */
2127 f_TC_attach(id);
2128
2129 /* HLR: cancel the location request */
2130 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2131 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002132
2133 /* ensure no Detach Request got received */
2134 timer T := 5.0;
2135 T.start;
2136 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002137 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002138 T.stop;
2139 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002140 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002141 }
2142 [] T.timeout {
2143 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002144 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002145 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002146 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002147 repeat;
2148 }
2149 }
2150}
2151
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002152/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2153private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2154 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2155
2156 /* first perform regular attach */
2157 f_TC_attach(id);
2158 /* then activate PDP context */
2159 f_pdp_ctx_act(apars);
2160 /* then transceive a downlink PDU */
2161 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2162
2163 /* Send Error indication as response from upload PDU and expect deact towards MS */
2164 f_pdp_ctx_deact_mt(apars, true);
2165}
2166testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2167 var BSSGP_ConnHdlr vc_conn;
2168 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002169 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_error_ind_ggsn), testcasename(), g_gb, 26);
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002170 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002171 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002172}
2173
Alexander Couzens5e307b42018-05-22 18:12:20 +02002174testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2175 /* MS <-> SGSN: GMM Attach
2176 * HLR -> SGSN: Cancel Location Request
2177 * HLR <- SGSN: Cancel Location Ack
2178 */
2179 var BSSGP_ConnHdlr vc_conn;
2180 f_init();
2181 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002182 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002183 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002184 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002185}
2186
2187
Alexander Couzensc87967a2018-05-22 16:09:54 +02002188private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2189 /* MS: perform regular attach */
2190 f_TC_attach(id);
2191
2192 /* HLR: cancel the location request */
2193 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2194 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2195 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2196
2197 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002198 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002199 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002200
2201 setverdict(pass);
2202}
2203
2204testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2205 /* MS <-> SGSN: GMM Attach
2206 * HLR -> SGSN: Cancel Location Request
2207 * HLR <- SGSN: Cancel Location Ack
2208 * MS <- SGSN: Detach Request
2209 * SGSN-> MS: Detach Complete
2210 */
2211 var BSSGP_ConnHdlr vc_conn;
2212 f_init();
2213 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002214 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002215 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002216 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002217}
2218
2219
Alexander Couzens6c47f292018-05-22 17:09:49 +02002220private function f_hlr_location_cancel_request_unknown_subscriber(
2221 charstring id,
2222 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2223
2224 /* HLR: cancel the location request */
2225 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2226
2227 /* cause 2 = IMSI_UNKNOWN */
2228 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2229
2230 setverdict(pass);
2231}
2232
2233private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002234 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002235}
2236
2237testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2238 /* HLR -> SGSN: Cancel Location Request
2239 * HLR <- SGSN: Cancel Location Error
2240 */
2241
2242 var BSSGP_ConnHdlr vc_conn;
2243 f_init();
2244 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002245 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002246 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002247 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002248}
2249
2250private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002251 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002252}
2253
2254testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2255 /* HLR -> SGSN: Cancel Location Request
2256 * HLR <- SGSN: Cancel Location Error
2257 */
2258
2259 var BSSGP_ConnHdlr vc_conn;
2260 f_init();
2261 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002262 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002263 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002264 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002265}
2266
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002267private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2268 f_TC_attach(id);
2269 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2270}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002271
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002272testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2273 /* MS <-> SGSN: Attach
2274 * MS -> SGSN: Detach Req (Power off)
2275 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2276 */
2277 var BSSGP_ConnHdlr vc_conn;
2278 var integer id := 33;
2279 var charstring imsi := hex2str(f_gen_imsi(id));
2280
2281 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002282 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002283 vc_conn.done;
2284
2285 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002286 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002287}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002288
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002289/* Attempt an attach, but loose the Identification Request (IMEI) */
2290private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2291 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002292 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002293
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002294 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002295
2296 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002297 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002298 /* break */
2299 }
Harald Welte955aa942019-05-03 01:29:29 +02002300 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002301 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002302 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002303 repeat;
2304 }
Harald Welte955aa942019-05-03 01:29:29 +02002305 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002306 /* ignore ID REQ IMEI */
2307 count_req := count_req + 1;
2308 repeat;
2309 }
2310 }
2311 if (count_req != 5) {
2312 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002313 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002314 }
2315 setverdict(pass);
2316}
2317
2318testcase TC_attach_no_imei_response() runs on test_CT {
2319 /* MS -> SGSN: Attach Request IMSI
2320 * MS <- SGSN: Identity Request IMSI (optional)
2321 * MS -> SGSN: Identity Response IMSI (optional)
2322 * MS <- SGSN: Identity Request IMEI
2323 * MS -x SGSN: no response
2324 * MS <- SGSN: re-send: Identity Request IMEI 4x
2325 * MS <- SGSN: Attach Reject
2326 */
2327 var BSSGP_ConnHdlr vc_conn;
2328 f_init();
2329 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002330 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb, 32, 60.0);
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002331 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002332 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002333}
2334
Alexander Couzens53f20562018-06-12 16:24:12 +02002335/* Attempt an attach, but loose the Identification Request (IMSI) */
2336private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2337 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002338 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002339
2340 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2341 g_pars.p_tmsi := 'c0000035'O;
2342
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002343 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02002344
2345 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002346 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002347 /* break */
2348 }
Harald Welte955aa942019-05-03 01:29:29 +02002349 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002350 /* ignore ID REQ IMSI */
2351 count_req := count_req + 1;
2352 repeat;
2353 }
Harald Welte955aa942019-05-03 01:29:29 +02002354 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002355 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002356 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002357 repeat;
2358 }
2359 }
2360 if (count_req != 5) {
2361 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002362 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002363 }
2364 setverdict(pass);
2365}
2366
2367testcase TC_attach_no_imsi_response() runs on test_CT {
2368 /* MS -> SGSN: Attach Request TMSI (unknown)
2369 * MS <- SGSN: Identity Request IMEI (optional)
2370 * MS -> SGSN: Identity Response IMEI (optional)
2371 * MS <- SGSN: Identity Request IMSI
2372 * MS -x SGSN: no response
2373 * MS <- SGSN: re-send: Identity Request IMSI 4x
2374 * MS <- SGSN: Attach Reject
2375 */
2376 var BSSGP_ConnHdlr vc_conn;
2377 f_init();
2378 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002379 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb, 35, 60.0);
Alexander Couzens53f20562018-06-12 16:24:12 +02002380 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002381 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002382}
2383
Alexander Couzenscf818962018-06-05 18:00:00 +02002384private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2385 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2386}
2387
2388testcase TC_attach_check_subscriber_list() runs on test_CT {
2389 /* MS <-> SGSN: Attach
2390 * VTY -> SGSN: Check if MS is in subscriber cache
2391 */
2392 var BSSGP_ConnHdlr vc_conn;
2393 var integer id := 34;
2394 var charstring imsi := hex2str(f_gen_imsi(id));
2395
2396 f_init();
2397 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002398 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002399 vc_conn.done;
2400
2401 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2402 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002403 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002404}
2405
Alexander Couzensf9858652018-06-07 16:14:53 +02002406private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2407 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002408 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002409
2410 /* unregister the old IMSI */
2411 f_bssgp_client_unregister(g_pars.imsi);
2412 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002413 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002414 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002415
2416 /* there is no auth */
2417 g_pars.net.expect_auth := false;
2418
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002419 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002420 f_gmm_auth();
2421 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002422 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002423 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002424 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002425 }
Harald Welte955aa942019-05-03 01:29:29 +02002426 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2427 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002428 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002429 setverdict(pass);
2430 }
2431 }
2432}
Alexander Couzens03d12242018-08-07 16:13:52 +02002433
2434private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2435
2436 f_TC_attach_closed_foreign(id);
2437 f_TC_attach_closed_imsi_added(id);
2438
2439}
2440
2441
Alexander Couzensf9858652018-06-07 16:14:53 +02002442testcase TC_attach_closed_add_vty() runs on test_CT {
2443 /* VTY-> SGSN: policy close
2444 * MS -> SGSN: Attach Request
2445 * MS <- SGSN: Identity Request IMSI
2446 * MS -> SGSN: Identity Response IMSI
2447 * MS <- SGSN: Attach Reject
2448 * VTY-> SGSN: policy imsi-acl add IMSI
2449 * MS -> SGSN: Attach Request
2450 * MS <- SGSN: Identity Request IMSI
2451 * MS -> SGSN: Identity Response IMSI
2452 * MS <- SGSN: Identity Request IMEI
2453 * MS -> SGSN: Identity Response IMEI
2454 * MS <- SGSN: Attach Accept
2455 */
2456 var BSSGP_ConnHdlr vc_conn;
2457 f_init();
2458 f_sleep(1.0);
2459 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2460 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002461 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2462 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002463 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002464 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002465 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002466 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002467}
2468
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469/* Attempt an attach, but never answer a Attach Complete */
2470private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2471 var integer count_req := 0;
2472
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002473 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02002474 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002475 /* Expect SGSN to perform LU with HLR */
2476 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002477
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002478 timer T := 10.0;
2479 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002480 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002481 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002482 /* break */
2483 }
Harald Welte955aa942019-05-03 01:29:29 +02002484 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002485 /* ignore */
2486 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002487 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002488 repeat;
2489 }
2490 }
2491 if (count_req != 5) {
2492 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002493 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002494 }
2495 setverdict(pass);
2496}
2497
2498testcase TC_attach_check_complete_resend() runs on test_CT {
2499 /* MS -> SGSN: Attach Request IMSI
2500 * MS <- SGSN: Identity Request *
2501 * MS -> SGSN: Identity Response *
2502 * MS <- SGSN: Attach Complete 5x
2503 */
2504 var BSSGP_ConnHdlr vc_conn;
2505 f_init();
2506 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002507 vc_conn := f_start_handler(refers(f_TC_attach_check_complete_resend), testcasename(), g_gb, 36, 60.0);
Alexander Couzens0085bd72018-06-12 19:08:44 +02002508 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002509 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002510}
2511
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002512friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002513 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002514 var PDU_DTAP_PS_MT mt;
2515 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002516
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002517 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002518 p_tmsi := g_pars.p_tmsi;
2519 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002520 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002521 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002522 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002523 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2524 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2525 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002526 setverdict(pass);
2527 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002528 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2529 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2530 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002531 setverdict(pass);
2532 }
2533
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002534 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002535 setverdict(fail, "Unexpected RAU Reject");
2536 mtc.stop;
2537 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002538 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002539 setverdict(fail, "Unexpected RAU Reject");
2540 mtc.stop;
2541 }
2542
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002543 [is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
Alexander Couzens5d56f522019-09-03 12:36:18 +02002544 key_sts := ?)) {
2545 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2546 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002547 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002548 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002549 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002550 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2551 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002552 }
2553}
2554
Alexander Couzensbfda9212018-07-31 03:17:33 +02002555private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002556 /* first perform regular attach */
2557 f_TC_attach(id);
2558
2559 /* then send RAU */
2560 f_routing_area_update(g_pars.ra);
2561
2562 /* do another RAU */
2563 f_routing_area_update(g_pars.ra);
2564
2565 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2566}
2567
2568testcase TC_attach_rau_a_a() runs on test_CT {
2569 /* MS <-> SGSN: Successful Attach
2570 * MS -> SGSN: Routing Area Update Request
2571 * MS <- SGSN: Routing Area Update Accept
2572 * MS -> SGSN: Routing Area Update Request
2573 * MS <- SGSN: Routing Area Update Accept
2574 * MS -> SGSN: Detach (PowerOff)
2575 */
2576 var BSSGP_ConnHdlr vc_conn;
2577 f_init();
2578 f_sleep(1.0);
2579 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2580 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002581 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002582}
2583
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002584private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002585 f_TC_attach(id);
2586
2587 log("attach complete sending rau");
2588 f_routing_area_update(g_pars.ra, 0);
2589
2590 log("rau complete unregistering");
2591 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002592 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002593
2594 log("sending second RAU via different RA");
2595 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2596
2597 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2598}
2599
2600testcase TC_attach_rau_a_b() runs on test_CT {
2601 /* MS <-> SGSN: Successful Attach
2602 * MS -> SGSN: Routing Area _a_ Update Request
2603 * MS <- SGSN: Routing Area _a_ Update Accept
2604 * MS -> SGSN: Routing Area _b_ Update Request
2605 * MS <- SGSN: Routing Area _b_ Update Accept
2606 * MS -> SGSN: Detach (PowerOff)
2607 */
2608 var BSSGP_ConnHdlr vc_conn;
2609 f_init();
2610 f_sleep(1.0);
2611 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2612 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002613 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002614}
2615
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002616private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2617 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002618 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002619 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002620 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002621
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002622 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002623
2624 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002625 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002626 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2627 mtc.stop;
2628 }
Harald Welte955aa942019-05-03 01:29:29 +02002629 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002630 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002631 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002632 repeat;
2633 }
Harald Welte955aa942019-05-03 01:29:29 +02002634 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002635 /* send out a second GMM_Attach Request.
2636 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2637 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002638 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002639 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002640 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002641 }
2642 }
2643 f_sleep(1.0);
2644
2645 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2646 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002647 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002648 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002649 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002650 repeat;
2651 }
Harald Welte955aa942019-05-03 01:29:29 +02002652 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002653 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2654 mtc.stop;
2655 }
Harald Welte955aa942019-05-03 01:29:29 +02002656 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002657 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2658 mtc.stop;
2659 }
Harald Welte955aa942019-05-03 01:29:29 +02002660 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2661 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002662 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002663 setverdict(pass);
2664 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2665 }
2666 }
2667}
2668
2669testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2670 /* Testing if the SGSN ignore Attach Request with the exact same content */
2671 /* MS -> SGSN: Attach Request IMSI
2672 * MS <- SGSN: Identity Request IMSI (optional)
2673 * MS -> SGSN: Identity Response IMSI (optional)
2674 * MS <- SGSN: Identity Request IMEI
2675 * MS -> SGSN: Attach Request (2nd)
2676 * MS <- SGSN: Identity Response IMEI
2677 * MS <- SGSN: Attach Accept
2678 * MS -> SGSN: Attach Complete
2679 */
2680 var BSSGP_ConnHdlr vc_conn;
2681 f_init();
2682 f_sleep(1.0);
2683 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2684 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2685 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002686 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002687}
2688
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002689private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002690 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2691
2692 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2693
2694 /* send Attach Request */
2695 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2696 * 3G auth vectors */
2697 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2698 /* The thing is, if the solSACapability is 'omit', then the
2699 * revisionLevelIndicatior is at the wrong place! */
2700 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002701 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002702
2703 /* do the auth */
2704 var PDU_L3_MS_SGSN l3_mo;
2705 var PDU_L3_SGSN_MS l3_mt;
2706 var default di := activate(as_mm_identity());
2707
2708 var GSUP_IE auth_tuple;
2709 var template AuthenticationParameterAUTNTLV autn;
2710
2711 g_pars.vec := f_gen_auth_vec_3g();
2712 autn := {
2713 elementIdentifier := '28'O,
2714 lengthIndicator := lengthof(g_pars.vec.autn),
2715 autnValue := g_pars.vec.autn
2716 };
2717 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2718 g_pars.vec.sres,
2719 g_pars.vec.kc,
2720 g_pars.vec.ik,
2721 g_pars.vec.ck,
2722 g_pars.vec.autn,
2723 g_pars.vec.res));
2724 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2725 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2726 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2727
2728 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2729 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002730 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002731
2732 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002733 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002734
2735 /* wait for the GSUP resync request */
2736 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2737 g_pars.imsi,
2738 g_pars.vec.auts,
2739 g_pars.vec.rand));
2740
2741 /* generate new key material */
2742 g_pars.vec := f_gen_auth_vec_3g();
2743 autn := {
2744 elementIdentifier := '28'O,
2745 lengthIndicator := lengthof(g_pars.vec.autn),
2746 autnValue := g_pars.vec.autn
2747 };
2748
2749 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2750 g_pars.vec.sres,
2751 g_pars.vec.kc,
2752 g_pars.vec.ik,
2753 g_pars.vec.ck,
2754 g_pars.vec.autn,
2755 g_pars.vec.res));
2756 /* send new key material */
2757 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2758
2759 /* wait for the new Auth Request */
2760 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2761 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002762 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002763 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2764 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2765 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2766 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2767 valueField := substr(g_pars.vec.res, 0, 4)
2768 };
2769 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2770 elementIdentifier := '21'O,
2771 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2772 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2773 };
2774 l3_mo := valueof(auth_ciph_resp);
2775 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2776 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2777 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2778 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2779 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002780 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002781 deactivate(di);
2782
2783 /* Expect SGSN to perform LU with HLR */
2784 f_gmm_gsup_lu_isd();
2785
Harald Welte955aa942019-05-03 01:29:29 +02002786 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2787 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002788 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002789 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002790 setverdict(pass);
2791}
2792
2793testcase TC_attach_usim_resync() runs on test_CT {
2794 /* MS -> SGSN: Attach Request
2795 * MS <- SGSN: Identity Request IMSI
2796 * MS -> SGSN: Identity Response IMSI
2797 * MS <- SGSN: Identity Request IMEI
2798 * MS -> SGSN: Identity Response IMEI
2799 * HLR<- SGSN: SAI Request
2800 * HLR-> SGSN: SAI Response
2801 * MS <- SGSN: Auth Request
2802 * MS -> SGSN: Auth Failure (with AUTS)
2803 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2804 * HLR-> SGSN: SAI Response (new key material)
2805 * MS <- SGSN: Auth Request (new key material)
2806 * MS -> SGSN: Auth Response
2807 * MS <- SGSN: Attach Accept
2808 * MS -> SGSN: Attach Complete
2809 */
2810 var BSSGP_ConnHdlr vc_conn;
2811 f_init();
2812 f_sleep(1.0);
2813 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2814 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002815 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002816}
2817
Harald Weltea05b8072019-04-23 22:35:05 +02002818
2819/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2820private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2821 f_gmm_attach(false, false);
2822 f_sleep(1.0);
2823 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2824 /* try to detach to check if SGSN is still alive */
2825 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2826}
2827testcase TC_llc_null() runs on test_CT {
2828 var BSSGP_ConnHdlr vc_conn;
2829 f_init();
2830 f_sleep(1.0);
2831 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2832 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002833 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002834}
2835
Harald Welte645a1512019-04-23 23:18:23 +02002836/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2837private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2838 f_gmm_attach(false, false);
2839 f_sleep(1.0);
2840 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002841 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002842 setverdict(pass);
2843}
2844testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2845 var BSSGP_ConnHdlr vc_conn;
2846 f_init();
2847 f_sleep(1.0);
2848 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2849 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002850 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002851}
2852
2853/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2854private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2855 f_gmm_attach(false, false);
2856 f_sleep(1.0);
2857 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002858 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002859 setverdict(pass);
2860}
2861testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2862 var BSSGP_ConnHdlr vc_conn;
2863 f_init();
2864 f_sleep(1.0);
2865 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2866 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002867 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002868}
2869
Harald Welte2aaac1b2019-05-02 10:02:53 +02002870/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2871private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2872 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2873 var template (value) XID_Information xid;
2874 var template XID_Information xid_rx;
2875
2876 /* first perform regular attach */
2877 f_TC_attach(id);
2878 /* then activate PDP context */
2879 f_pdp_ctx_act(apars);
2880
2881 /* start MO XID */
2882 xid := { ts_XID_L3(''O) };
2883 xid_rx := { tr_XID_L3(''O) };
2884 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2885 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002886 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002887 [] as_xid(apars);
2888 }
2889 setverdict(pass);
2890}
2891testcase TC_xid_empty_l3() runs on test_CT {
2892 var BSSGP_ConnHdlr vc_conn;
2893 f_init();
2894 f_sleep(1.0);
2895 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2896 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002897 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002898}
2899
2900private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2901 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2902 var template (value) XID_Information xid;
2903 var template XID_Information xid_rx;
2904
2905 /* first perform regular attach */
2906 f_TC_attach(id);
2907 /* then activate PDP context */
2908 f_pdp_ctx_act(apars);
2909
2910 /* start MO XID */
2911 xid := { ts_XID_N201U(1234) };
2912 xid_rx := { tr_XID_N201U(1234) };
2913 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2914 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002915 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002916 [] as_xid(apars);
2917 }
2918 setverdict(pass);
2919}
2920testcase TC_xid_n201u() runs on test_CT {
2921 var BSSGP_ConnHdlr vc_conn;
2922 f_init();
2923 f_sleep(1.0);
2924 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2925 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002926 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002927}
2928
Alexander Couzens6bee0872019-05-11 01:48:50 +02002929private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2930 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2931
2932 /* first perform regular attach */
2933 f_TC_attach(id);
2934 /* then activate PDP context */
2935 f_pdp_ctx_act(apars);
2936 /* do a normal detach */
2937 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2938}
2939
2940testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2941 /* MS -> SGSN: Attach Request
2942 * MS <-> SGSN: [..]
2943 * MS -> SGSN: Attach Complete
2944 * MS -> SGSN: PDP Activate Request
2945 * MS <- SGSN: PDP Activate Accept
2946 * MS -> SGSN: GMM Detach Request
2947 * MS <- SGSN: GMM Detach Accept
2948 */
2949 var BSSGP_ConnHdlr vc_conn;
2950 f_init();
2951 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2952 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002953 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002954}
Harald Welte645a1512019-04-23 23:18:23 +02002955
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002956private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2957 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2958 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2959 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2960 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2961 var PDU_L3_SGSN_MS l3_mt;
2962
2963 f_send_l3(attach_req, 0);
2964
2965 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2966
2967 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2968 alt {
2969 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2970 setverdict(pass);
2971 }
2972 [] BSSGP[0].receive { repeat; }
2973 }
2974}
2975
2976/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2977 * See OS#3957 and OS#4245 for more information.
2978 */
2979testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2980 /*
2981 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2982 * MS <-- SGSN: Identity Request (IMEI)
2983 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2984 */
2985 var BSSGP_ConnHdlr vc_conn;
2986 f_init();
2987 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2988 vc_conn.done;
2989 f_cleanup();
2990}
2991
Harald Welte8e5932e2020-06-17 22:12:54 +02002992private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2993var PDU_BSSGP rx;
2994[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2995 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2996 mtc.stop;
2997 }
2998}
2999
3000/* SUSPEND, then DL traffic: should not pass + no paging expected */
3001private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3002 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3003 var default d;
3004
3005 /* first perform regular attach */
3006 f_TC_attach(id);
3007 /* then activate PDP context */
3008 f_pdp_ctx_act(apars);
3009 /* then transceive a downlink PDU */
3010 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3011
3012 /* now suspend GPRS */
3013 f_bssgp_suspend();
3014
3015 d := activate(as_nopaging_ps());
3016
3017 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3018 * nor any related paging requests */
3019 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3020
3021 deactivate(d);
3022}
3023testcase TC_suspend_nopaging() runs on test_CT {
3024 var BSSGP_ConnHdlr vc_conn;
3025 f_init();
3026 f_sleep(1.0);
3027 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3028 vc_conn.done;
3029 f_cleanup();
3030}
3031
3032
3033/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3034private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3035 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3036 var OCT1 susp_ref;
3037 var default d;
3038
3039 /* first perform regular attach */
3040 f_TC_attach(id);
3041 /* then activate PDP context */
3042 f_pdp_ctx_act(apars);
3043 /* then transceive a downlink PDU */
3044 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3045
3046 /* now suspend GPRS */
3047 susp_ref := f_bssgp_suspend();
3048
3049 d := activate(as_nopaging_ps());
3050
3051 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3052 * nor any related paging requests */
3053 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3054
3055 deactivate(d);
3056
3057 /* resume GPRS */
3058 f_bssgp_resume(susp_ref);
3059
3060 /* now data should be flowing again */
3061 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3062}
3063testcase TC_suspend_resume() runs on test_CT {
3064 var BSSGP_ConnHdlr vc_conn;
3065 f_init();
3066 f_sleep(1.0);
3067 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3068 vc_conn.done;
3069 f_cleanup();
3070}
3071
3072/* SUSPEND, then RAU: data expected to flow after implicit resume */
3073private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3074 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3075 var default d;
3076
3077 /* first perform regular attach */
3078 f_TC_attach(id);
3079 /* then activate PDP context */
3080 f_pdp_ctx_act(apars);
3081 /* then transceive a downlink PDU */
3082 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3083
3084 /* now suspend GPRS */
3085 f_bssgp_suspend();
3086
3087 d := activate(as_nopaging_ps());
3088
3089 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3090 * nor any related paging requests */
3091 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3092
3093 deactivate(d);
3094
3095 /* perform RAU (implicit RESUME) */
3096 f_routing_area_update(g_pars.ra);
3097
3098 /* now data should be flowing again */
3099 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3100
3101}
3102testcase TC_suspend_rau() runs on test_CT {
3103 var BSSGP_ConnHdlr vc_conn;
3104 f_init();
3105 f_sleep(1.0);
3106 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3107 vc_conn.done;
3108 f_cleanup();
3109}
3110
3111
3112/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3113private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3114 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3115 var default d;
3116
3117 /* first perform regular attach */
3118 f_TC_attach(id);
3119 /* then activate PDP context */
3120 f_pdp_ctx_act(apars);
3121 /* then transceive a downlink PDU */
3122 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3123
3124 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3125 f_sleep(5.0);
3126
3127 /* now data should be flowing again, but with PS PAGING */
3128 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3129 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3130
3131 /* FIXME: simulate paging response */
3132 /* FIXME: verify PDU actually arrives only after paging response was successful */
3133
3134}
3135testcase TC_paging_ps() runs on test_CT {
3136 var BSSGP_ConnHdlr vc_conn;
3137 f_init();
3138 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3139 f_sleep(1.0);
3140 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3141 vc_conn.done;
3142 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3143 f_cleanup();
3144}
3145
Philipp Maier7df55e02020-12-14 23:46:04 +01003146private function f_TC_bssgp_rim_dummy(charstring id) runs on BSSGP_ConnHdlr {
3147}
3148
3149/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3150 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3151 * other and vice versa. */
3152testcase TC_bssgp_rim_single_report() runs on test_CT {
3153 var BSSGP_ConnHdlr vc_conn;
3154 f_init();
3155 vc_conn := f_start_handler(refers(f_TC_bssgp_rim_dummy), testcasename(), g_gb, 17);
3156 vc_conn.done;
3157
3158 timer T := 2.0;
3159
3160 var template RIM_Routing_Address dst_addr;
3161 var template RIM_Routing_Address src_addr;
3162 var template RAN_Information_Request_RIM_Container req_cont;
3163 var template RAN_Information_RIM_Container res_cont;
3164 var template PDU_BSSGP bssgp_rim_pdu;
3165 var template PDU_BSSGP bssgp_rim_pdu_expect;
3166
3167 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3168 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003169
3170
Philipp Maier7df55e02020-12-14 23:46:04 +01003171 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3172 * based on the cell id in dst_addr to GB interface #1. */
3173 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3174 ts_RIM_Sequence_Number(1),
3175 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3176 ts_RIM_Protocol_Version_Number(1),
3177 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3178 omit);
3179 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3180 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3181 req_cont);
3182 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3183 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3184 tr_RAN_Information_Request_RIM_Container);
3185 RIM[0].send(bssgp_rim_pdu);
3186 T.start;
3187 alt {
3188 [] RIM[1].receive(bssgp_rim_pdu_expect) { }
3189 [] RIM[1].receive {
3190 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3191 }
3192 [] T.timeout {
3193 setverdict(fail, "No BSSGP RIM PDU received");
3194 mtc.stop;
3195 }
3196 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003197
Philipp Maier7df55e02020-12-14 23:46:04 +01003198 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3199 * GB interface #0 */
3200 var octetstring si1 := '198fb100000000000000000000000000007900002b'O;
3201 var octetstring si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
3202 var octetstring si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
3203 var octetstring si := si1 & si3 & si13;
3204
3205 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3206 ts_RIM_Sequence_Number(2),
3207 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3208 ts_RIM_Protocol_Version_Number(1),
3209 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si)),
3210 omit);
3211 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3212 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3213 res_cont);
3214 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3215 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3216 ?);
3217 RIM[1].send(bssgp_rim_pdu);
3218 T.start;
3219 alt {
3220 [] RIM[0].receive(bssgp_rim_pdu_expect) { }
3221 [] RIM[0].receive {
3222 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3223 }
3224 [] T.timeout {
3225 setverdict(fail, "No BSSGP RIM PDU received");
3226 mtc.stop;
3227 }
3228 }
3229
3230 f_cleanup();
3231}
Harald Welte8e5932e2020-06-17 22:12:54 +02003232
Harald Welte5ac31492018-02-15 20:39:13 +01003233control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003234 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003235 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003236 execute( TC_attach_umts_aka_umts_res() );
3237 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003238 execute( TC_attach_auth_id_timeout() );
3239 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003240 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003241 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003242 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003243 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003244 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003245 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003246 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003247 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003248 execute( TC_attach_closed_add_vty(), 20.0 );
3249 execute( TC_attach_check_subscriber_list(), 20.0 );
3250 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003251 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003252 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3253 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3254 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3255 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003256 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003257 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003258 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003259 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003260 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003261 execute( TC_detach_unknown_nopoweroff() );
3262 execute( TC_detach_unknown_poweroff() );
3263 execute( TC_detach_nopoweroff() );
3264 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003265 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003266 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003267 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003268 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003269 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003270 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003271 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003272 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003273 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003274 execute( TC_attach_restart_ctr_echo() );
3275 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003276 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003277 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3278 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003279 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003280 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003281 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003282
Harald Welte2aaac1b2019-05-02 10:02:53 +02003283 execute( TC_xid_empty_l3() );
3284 execute( TC_xid_n201u() );
3285
Harald Weltea05b8072019-04-23 22:35:05 +02003286 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003287 execute( TC_llc_sabm_dm_llgmm() );
3288 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003289
Harald Welte8e5932e2020-06-17 22:12:54 +02003290 execute( TC_suspend_nopaging() );
3291 execute( TC_suspend_resume() );
3292 execute( TC_suspend_rau() );
3293 execute( TC_paging_ps() );
3294
Philipp Maier7df55e02020-12-14 23:46:04 +01003295 execute( TC_bssgp_rim_single_report() );
3296
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003297 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3298 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003299}
Harald Welte96a33b02018-02-04 10:36:22 +01003300
3301
3302
3303}