blob: 7d47a1ffcd74eb74618f10cc6fc1aa8f1e579988 [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],
Alexander Couzens89508702018-07-31 04:16:10 +0200239 lac := int2oct(cell_id.ra_id.lai.lac, 16),
240 rac := int2oct(cell_id.ra_id.rac, 8)
241 }
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
Harald Welte04683d02018-02-16 22:43:45 +0100768function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
769 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100770 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200771 if (not (g_pars.bssgp_cell_id[0].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)
Alexander Couzens51114d12018-07-31 18:41:56 +0200773 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].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 }
Harald Weltef70997d2018-02-17 10:11:19 +0100782 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100783 }
784 if (ispresent(aa.msIdentity)) {
785 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200786 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100787 }
788 /* P-TMSI.sig */
789 if (ispresent(aa.ptmsiSignature)) {
790 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
791 }
792 /* updateTimer */
793 // aa.readyTimer
794 /* T3302, T3319, T3323, T3312_ext, T3324 */
795}
796
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200797function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100798 /* mandatory IE */
799 g_pars.ra := ra.routingAreaId;
800 if (ispresent(ra.allocatedPTMSI)) {
801 if (not g_pars.net.expect_ptmsi) {
802 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200803 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100804 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200805 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100806 }
807 if (ispresent(ra.msIdentity)) {
808 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200809 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100810 }
811 /* P-TMSI.sig */
812 if (ispresent(ra.ptmsiSignature)) {
813 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
814 }
815 /* updateTimer */
816 // aa.readyTimer
817 /* T3302, T3319, T3323, T3312_ext, T3324 */
818}
819
820
Harald Welte5a4fa042018-02-16 20:59:21 +0100821function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
822 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
823}
824
Harald Welte23178c52018-02-17 09:36:33 +0100825/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700826private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100827 if (ispresent(g_pars.p_tmsi)) {
828 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
829 } else {
830 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
831 }
832}
833
Harald Welte311ec272018-02-17 09:40:03 +0100834private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100835 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100836 /* Expect MSC to perform LU with HLR */
837 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100838 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
839 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
840 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100841 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
842 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
843}
844
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200845friend 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 +0100846 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200847 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 +0200848 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100849
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200850 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
851 * 3G auth vectors */
852 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
853 /* The thing is, if the solSACapability is 'omit', then the
854 * revisionLevelIndicatior is at the wrong place! */
855 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
856
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200857 f_send_l3(attach_req, ran_index);
858 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200859 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100860 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100861
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200862 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200863 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
864
Harald Welte04683d02018-02-16 22:43:45 +0100865 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200866 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200867
868 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200869 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200870 as_iu_release_compl_disc();
871 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200872
873 /* Race condition
874 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
875 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
876 * arrived before it. This results in a test case failure.
877 * Delay execution by 50 ms
878 */
879 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200880}
881
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200882friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
883 timer T := 5.0;
884 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100885 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 +0200886 T.start;
887 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100888 [] 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 +0200889 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
890 }
Harald Welte9b461a92020-12-10 23:41:14 +0100891 [] 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 +0200892 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
893 mtc.stop;
894 }
895 [] T.timeout {
896 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
897 mtc.stop;
898 }
899 }
900 return '00'O;
901}
902
903friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
904 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100905 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 +0200906 T.start;
907 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100908 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
909 [] 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 +0200910?)) {
911 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
912 mtc.stop;
913 }
914 [] T.timeout {
915 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
916 mtc.stop;
917 }
918 }
919}
920
921
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200922private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
923 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100924 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100925}
926
927testcase TC_attach() runs on test_CT {
928 var BSSGP_ConnHdlr vc_conn;
929 f_init();
930 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200931 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100932 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200933 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100934}
935
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100936testcase TC_attach_mnc3() runs on test_CT {
937 var BSSGP_ConnHdlr vc_conn;
938 f_init('023042'H);
939 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200940 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100941 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200942 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100943}
944
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200945private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
946 f_gmm_attach(true, false);
947 setverdict(pass);
948}
949testcase TC_attach_umts_aka_umts_res() runs on test_CT {
950 var BSSGP_ConnHdlr vc_conn;
951 f_init();
952 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200953 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200954 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200955 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200956}
957
958private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
959 f_gmm_attach(true, true);
960 setverdict(pass);
961}
962testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
963 var BSSGP_ConnHdlr vc_conn;
964 f_init();
965 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200966 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200967 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200968 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200969}
970
Harald Welte5b7c8122018-02-16 21:48:17 +0100971/* MS never responds to ID REQ, expect ATTACH REJECT */
972private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100973 var RoutingAreaIdentificationV old_ra := f_random_RAI();
974
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200975 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100976 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200977 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100978 /* don't send ID Response */
979 repeat;
980 }
Harald Welte955aa942019-05-03 01:29:29 +0200981 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100982 setverdict(pass);
983 }
Harald Welte955aa942019-05-03 01:29:29 +0200984 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100985 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200986 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100987 }
988 }
989}
990testcase TC_attach_auth_id_timeout() runs on test_CT {
991 var BSSGP_ConnHdlr vc_conn;
992 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200993 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 +0100994 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200995 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100996}
997
998/* HLR never responds to SAI REQ, expect ATTACH REJECT */
999private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001000 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1001
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001002 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001003 alt {
1004 [] as_mm_identity();
1005 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1006 }
1007 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001008 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001009 setverdict(pass);
1010}
1011testcase TC_attach_auth_sai_timeout() runs on test_CT {
1012 var BSSGP_ConnHdlr vc_conn;
1013 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001014 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001015 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001016 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001017}
1018
Harald Weltefe253882018-02-17 09:25:00 +01001019/* HLR rejects SAI, expect ATTACH REJECT */
1020private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001021 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1022
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001023 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001024 alt {
1025 [] as_mm_identity();
1026 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1027 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1028 }
1029 }
Harald Welte955aa942019-05-03 01:29:29 +02001030 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001031 setverdict(pass);
1032}
1033testcase TC_attach_auth_sai_reject() runs on test_CT {
1034 var BSSGP_ConnHdlr vc_conn;
1035 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001036 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001037 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001038 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001039}
1040
Harald Welte5b7c8122018-02-16 21:48:17 +01001041/* HLR never responds to UL REQ, expect ATTACH REJECT */
1042private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001043 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001044 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1045
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001046 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001047 f_gmm_auth();
1048 /* Expect MSC to perform LU with HLR */
1049 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1050 /* Never follow-up with ISD_REQ or UL_RES */
1051 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001052 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001053 setverdict(pass);
1054 }
Harald Welte955aa942019-05-03 01:29:29 +02001055 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1056 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001057 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001058 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001059 }
1060 }
1061}
1062testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1063 var BSSGP_ConnHdlr vc_conn;
1064 f_init();
1065 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001066 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001067 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001068 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001069}
1070
Harald Welteb7c14e92018-02-17 09:29:16 +01001071/* HLR rejects UL REQ, expect ATTACH REJECT */
1072private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001073 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001074 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1075
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001076 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001077 f_gmm_auth();
1078 /* Expect MSC to perform LU with HLR */
1079 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1080 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1081 }
1082 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001083 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001084 setverdict(pass);
1085 }
Harald Welte955aa942019-05-03 01:29:29 +02001086 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1087 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001088 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001089 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001090 }
1091 }
1092}
1093testcase TC_attach_gsup_lu_reject() runs on test_CT {
1094 var BSSGP_ConnHdlr vc_conn;
1095 f_init();
1096 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001097 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001098 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001099 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001100}
1101
1102
Harald Welte3823e2e2018-02-16 21:53:48 +01001103/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1104private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001105 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001106 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1107
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001108 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001109 f_gmm_auth();
1110 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001111 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001112
Harald Welte955aa942019-05-03 01:29:29 +02001113 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1114 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001115 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001116 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001117 setverdict(pass);
1118}
Harald Welte3823e2e2018-02-16 21:53:48 +01001119testcase TC_attach_combined() runs on test_CT {
1120 var BSSGP_ConnHdlr vc_conn;
1121 f_init();
1122 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001123 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001124 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001125 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001126}
1127
Harald Welte76dee092018-02-16 22:12:59 +01001128/* Attempt of GPRS ATTACH in 'accept all' mode */
1129private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001130 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001131 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1132
1133 g_pars.net.expect_auth := false;
1134
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001135 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001136 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001137 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1138 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001139 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001140 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001141 setverdict(pass);
1142}
1143testcase TC_attach_accept_all() runs on test_CT {
1144 var BSSGP_ConnHdlr vc_conn;
1145 f_init();
1146 f_sleep(1.0);
1147 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001148 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001149 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001150 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001151}
Harald Welte5b7c8122018-02-16 21:48:17 +01001152
Harald Welteb2124b22018-02-16 22:26:56 +01001153/* Attempt of GPRS ATTACH in 'accept all' mode */
1154private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001155 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1156
1157 /* Simulate a foreign IMSI */
1158 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001159 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001160
1161 g_pars.net.expect_auth := false;
1162
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001163 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001164 alt {
1165 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001166 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001167 setverdict(pass);
1168 }
Harald Welte955aa942019-05-03 01:29:29 +02001169 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001170 setverdict(pass);
1171 }
Harald Welte955aa942019-05-03 01:29:29 +02001172 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001173 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001174 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001175 }
Harald Welteb2124b22018-02-16 22:26:56 +01001176 }
1177}
1178testcase TC_attach_closed() runs on test_CT {
1179 var BSSGP_ConnHdlr vc_conn;
1180 f_init();
1181 f_sleep(1.0);
1182 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1183 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001184 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001185 vc_conn.done;
1186 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001187 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001188 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001189 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001190}
1191
Harald Welte04683d02018-02-16 22:43:45 +01001192/* Routing Area Update from Unknown TLLI -> REJECT */
1193private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001194 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1195
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001196 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 +01001197 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001198 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001199 setverdict(pass);
1200 }
1201 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001202 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001203 }
1204}
1205testcase TC_rau_unknown() runs on test_CT {
1206 var BSSGP_ConnHdlr vc_conn;
1207 f_init();
1208 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001209 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001210 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001211 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001212}
1213
Harald Welte91636de2018-02-17 10:16:14 +01001214private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001215 /* first perform regular attach */
1216 f_TC_attach(id);
1217
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001218 f_routing_area_update(g_pars.ra);
1219
Harald Welte91636de2018-02-17 10:16:14 +01001220}
1221testcase TC_attach_rau() runs on test_CT {
1222 var BSSGP_ConnHdlr vc_conn;
1223 f_init();
1224 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001225 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001226 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001227 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001228}
Harald Welte04683d02018-02-16 22:43:45 +01001229
Harald Welte6abb9fe2018-02-17 15:24:48 +01001230/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001231function 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 +02001232 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001233 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001234 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001235 if (expect_purge) {
1236 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1237 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1238 }
1239 T.start;
1240 alt {
1241 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1242 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001243 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001244 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001245 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001246 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001247 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001248 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001249 /* TODO: check if any PDP contexts are deactivated on network side? */
1250 }
1251 [power_off] T.timeout {
1252 setverdict(pass);
1253 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001254 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001255 g_pars.ra := omit;
1256 setverdict(pass);
1257 /* TODO: check if any PDP contexts are deactivated on network side? */
1258 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001259 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001260 if (power_off) {
1261 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1262 } else {
1263 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1264 }
1265 mtc.stop;
1266 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001267 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001268 }
1269}
1270
1271/* IMSI DETACH (non-power-off) for unknown TLLI */
1272private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1273 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1274}
1275testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1276 var BSSGP_ConnHdlr vc_conn;
1277 f_init();
1278 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001279 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001280 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001281 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001282}
1283
1284/* IMSI DETACH (power-off) for unknown TLLI */
1285private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1286 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1287}
1288testcase TC_detach_unknown_poweroff() runs on test_CT {
1289 var BSSGP_ConnHdlr vc_conn;
1290 f_init();
1291 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001292 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001293 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001294 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001295}
1296
1297/* IMSI DETACH (non-power-off) for known TLLI */
1298private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1299 /* first perform regular attach */
1300 f_TC_attach(id);
1301
1302 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1303}
1304testcase TC_detach_nopoweroff() runs on test_CT {
1305 var BSSGP_ConnHdlr vc_conn;
1306 f_init();
1307 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001308 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001309 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001310 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001311}
1312
1313/* IMSI DETACH (power-off) for known TLLI */
1314private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1315 /* first perform regular attach */
1316 f_TC_attach(id);
1317
1318 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1319}
1320testcase TC_detach_poweroff() runs on test_CT {
1321 var BSSGP_ConnHdlr vc_conn;
1322 f_init();
1323 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001324 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001325 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001326 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001327}
1328
Harald Welteeded9ad2018-02-17 20:57:34 +01001329type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001330 BIT3 tid, /* L3 Transaction ID */
1331 BIT4 nsapi, /* SNDCP NSAPI */
1332 BIT4 sapi, /* LLC SAPI */
1333 QoSV qos, /* QoS parameters */
1334 PDPAddressV addr, /* IP address */
1335 octetstring apn optional, /* APN name */
1336 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1337 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001338 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001339 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001340
Harald Welte822f9102018-02-18 20:39:06 +01001341 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1342 OCT4 ggsn_tei_u, /* GGSN TEI User */
1343 octetstring ggsn_ip_c, /* GGSN IP Control */
1344 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001345 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001346
Harald Welte822f9102018-02-18 20:39:06 +01001347 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1348 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1349 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1350 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001351};
1352
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001353
1354private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1355 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1356 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1357 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1358 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1359 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1360 f_gtp_register_teid(apars.ggsn_tei_c);
1361 f_gtp_register_teid(apars.ggsn_tei_u);
1362}
1363
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001364function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001365runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001366 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1367 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001368 var template Recovery_gtpc recovery := omit;
1369
1370 if (send_recovery) {
1371 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1372 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001373
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001374 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 +02001375 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001376 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1377 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1378 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1379 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1380 apars.sgsn_tei_c, apars.gtp_resp_cause,
1381 apars.ggsn_tei_c, apars.ggsn_tei_u,
1382 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001383 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1384 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001385 }
1386 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001387 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001388 setverdict(pass);
1389 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001390 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001391 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001392 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001393 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001394 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001395 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001396 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001397 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001398 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001399 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1400 mtc.stop;
1401 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001402 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001403 setverdict(pass);
1404 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001405 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001406 }
1407}
1408
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001409function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001410runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001411 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1412 var Gtp1cUnitdata g_ud;
1413
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001414 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001415 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1416 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001417 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001418 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1419 }
1420 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001421 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001422 setverdict(pass);
1423 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001424 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001425 }
1426}
1427
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001428function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001429runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001430 var Gtp1cUnitdata g_ud;
1431 var integer seq_nr := 23;
1432 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1433
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001434 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001435 if (error_ind) {
1436 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1437 } else {
1438 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1439 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001440
1441 timer T := 5.0;
1442 T.start;
1443
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001444 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001445 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1446 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001447 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001448 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1449 repeat;
1450 }
1451 [] T.timeout {
1452 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1453 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001454 }
1455}
1456
Harald Welte6f203162018-02-18 22:04:55 +01001457
Harald Welteeded9ad2018-02-17 20:57:34 +01001458/* Table 10.5.156/3GPP TS 24.008 */
1459template (value) QoSV t_QosDefault := {
1460 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1461 delayClass := '100'B, /* best effort */
1462 spare1 := '00'B,
1463 precedenceClass := '010'B, /* normal */
1464 spare2 := '0'B,
1465 peakThroughput := '0000'B, /* subscribed */
1466 meanThroughput := '00000'B, /* subscribed */
1467 spare3 := '000'B,
1468 deliverErroneusSDU := omit,
1469 deliveryOrder := omit,
1470 trafficClass := omit,
1471 maxSDUSize := omit,
1472 maxBitrateUplink := omit,
1473 maxBitrateDownlink := omit,
1474 sduErrorRatio := omit,
1475 residualBER := omit,
1476 trafficHandlingPriority := omit,
1477 transferDelay := omit,
1478 guaranteedBitRateUplink := omit,
1479 guaranteedBitRateDownlink := omit,
1480 sourceStatisticsDescriptor := omit,
1481 signallingIndication := omit,
1482 spare4 := omit,
1483 maxBitrateDownlinkExt := omit,
1484 guaranteedBitRateDownlinkExt := omit,
1485 maxBitrateUplinkExt := omit,
1486 guaranteedBitRateUplinkExt := omit,
1487 maxBitrateDownlinkExt2 := omit,
1488 guaranteedBitRateDownlinkExt2 := omit,
1489 maxBitrateUplinkExt2 := omit,
1490 guaranteedBitRateUplinkExt2 := omit
1491}
1492
1493/* 10.5.6.4 / 3GPP TS 24.008 */
1494template (value) PDPAddressV t_AddrIPv4dyn := {
1495 pdpTypeOrg := '0001'B, /* IETF */
1496 spare := '0000'B,
1497 pdpTypeNum := '21'O, /* IPv4 */
1498 addressInfo := omit
1499}
1500template (value) PDPAddressV t_AddrIPv6dyn := {
1501 pdpTypeOrg := '0001'B, /* IETF */
1502 spare := '0000'B,
1503 pdpTypeNum := '53'O, /* IPv6 */
1504 addressInfo := omit
1505}
1506
Harald Welte37692d82018-02-18 15:21:34 +01001507template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001508 tid := '000'B,
1509 nsapi := '0101'B, /* < 5 are reserved */
1510 sapi := '0011'B, /* 3/5/9/11 */
1511 qos := t_QosDefault,
1512 addr := t_AddrIPv4dyn,
1513 apn := omit,
1514 pco := omit,
1515 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001516 gtp_resp_cause := int2oct(128, 1),
1517 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001518
1519 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001520 ggsn_tei_c := f_rnd_octstring(4),
1521 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001522 ggsn_ip_c := f_inet_addr(ggsn_ip),
1523 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001524 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001525
Harald Welteeded9ad2018-02-17 20:57:34 +01001526 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001527 sgsn_tei_u := omit,
1528 sgsn_ip_c := omit,
1529 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001530}
1531
Harald Welte37692d82018-02-18 15:21:34 +01001532template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1533 connId := 1,
1534 remName := f_inet_ntoa(ip),
1535 remPort := GTP1U_PORT
1536}
1537
1538template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1539 connId := 1,
1540 remName := f_inet_ntoa(ip),
1541 remPort := GTP1C_PORT
1542}
1543
1544private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1545 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1546 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1547}
1548
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001549private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1550 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001551 repeat;
1552 }
1553}
1554
1555template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1556 pDU_SN_UNITDATA := {
1557 nsapi := nsapi,
1558 moreBit := ?,
1559 snPduType := '1'B,
1560 firstSegmentIndicator := ?,
1561 spareBit := ?,
1562 pcomp := ?,
1563 dcomp := ?,
1564 npduNumber := ?,
1565 segmentNumber := ?,
1566 npduNumberContinued := ?,
1567 dataSegmentSnUnitdataPdu := payload
1568 }
1569}
1570
1571/* simple case: single segment, no compression */
1572template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1573 pDU_SN_UNITDATA := {
1574 nsapi := nsapi,
1575 moreBit := '0'B,
1576 snPduType := '1'B,
1577 firstSegmentIndicator := '1'B,
1578 spareBit := '0'B,
1579 pcomp := '0000'B,
1580 dcomp := '0000'B,
1581 npduNumber := '0000'B,
1582 segmentNumber := '0000'B,
1583 npduNumberContinued := '00'O,
1584 dataSegmentSnUnitdataPdu := payload
1585 }
1586}
1587
1588/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001589private 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 +02001590runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001591 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001592 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1593 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001594 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001595 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1596 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001597 [] as_xid(apars, ran_index);
1598 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001599 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1600 [expect_fwd] T.timeout {
1601 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1602 mtc.stop;
1603 }
1604 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1605 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1606 mtc.stop;
1607 }
1608 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001609 }
1610}
1611
Harald Welte64d6b512020-06-17 16:42:00 +02001612/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001613private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001614runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001615 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1616 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1617 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001618 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001619 /* Expect PDU via GTP from SGSN on simulated GGSN */
1620 alt {
1621 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1622 }
1623}
1624
Harald Welteeded9ad2018-02-17 20:57:34 +01001625private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001626 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001627
1628 /* first perform regular attach */
1629 f_TC_attach(id);
1630
1631 f_pdp_ctx_act(apars);
1632}
1633testcase TC_attach_pdp_act() runs on test_CT {
1634 var BSSGP_ConnHdlr vc_conn;
1635 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001636 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001637 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001638 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001639}
Harald Welteb2124b22018-02-16 22:26:56 +01001640
Harald Welte835b15f2018-02-18 14:39:11 +01001641/* PDP Context activation for not-attached subscriber; expect fail */
1642private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001643 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001644 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 +01001645 apars.apn, apars.pco));
1646 alt {
1647 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001648 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001649 setverdict(pass);
1650 }
1651 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1652 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001653 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001654 }
Harald Welte955aa942019-05-03 01:29:29 +02001655 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001656 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001657 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001658 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001659 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001660 }
1661}
1662testcase TC_pdp_act_unattached() runs on test_CT {
1663 var BSSGP_ConnHdlr vc_conn;
1664 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001665 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001666 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001667 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001668}
1669
Harald Welte37692d82018-02-18 15:21:34 +01001670/* ATTACH + PDP CTX ACT + user plane traffic */
1671private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1672 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1673
1674 /* first perform regular attach */
1675 f_TC_attach(id);
1676 /* then activate PDP context */
1677 f_pdp_ctx_act(apars);
1678 /* then transceive a downlink PDU */
1679 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1680 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1681}
1682testcase TC_attach_pdp_act_user() runs on test_CT {
1683 var BSSGP_ConnHdlr vc_conn;
1684 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001685 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001686 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001687 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001688}
1689
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001690/* ATTACH + PDP CTX ACT; reject from GGSN */
1691private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1692 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1693
1694 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1695 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1696
1697 /* first perform regular attach */
1698 f_TC_attach(id);
1699 /* then activate PDP context */
1700 f_pdp_ctx_act(apars);
1701}
1702testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1703 var BSSGP_ConnHdlr vc_conn;
1704 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001705 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001706 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001707 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001708}
Harald Welte835b15f2018-02-18 14:39:11 +01001709
Harald Welte6f203162018-02-18 22:04:55 +01001710/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1711private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1712 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1713
1714 /* first perform regular attach */
1715 f_TC_attach(id);
1716 /* then activate PDP context */
1717 f_pdp_ctx_act(apars);
1718 /* then transceive a downlink PDU */
1719 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1720 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1721
1722 f_pdp_ctx_deact_mo(apars, '00'O);
1723}
1724testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1725 var BSSGP_ConnHdlr vc_conn;
1726 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001727 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 +01001728 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001729 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001730}
1731
Harald Welte57b9b7f2018-02-18 22:28:13 +01001732/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1733private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1734 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1735
1736 /* first perform regular attach */
1737 f_TC_attach(id);
1738 /* then activate PDP context */
1739 f_pdp_ctx_act(apars);
1740 /* then transceive a downlink PDU */
1741 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1742 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1743
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001744 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001745}
1746testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1747 var BSSGP_ConnHdlr vc_conn;
1748 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001749 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 +01001750 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001751 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001752}
1753
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001754/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1755private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1756 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1757 var Gtp1cUnitdata g_ud;
1758 var integer i;
1759 var OCT1 cause_regular_deact := '24'O;
1760
1761 /* first perform regular attach + PDP context act */
1762 f_TC_attach(id);
1763 f_pdp_ctx_act(apars);
1764
1765 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1766 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1767
1768 for (i := 0; i < 2; i := i+1) {
1769 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1770 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1771 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1772 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1773 }
1774 }
1775
1776 alt {
1777 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1778 setverdict(pass);
1779 }
1780 [] as_xid(apars, 0);
1781 }
1782
1783 /* Make sure second DeactPdpAccept is sent: */
1784 timer T := 2.0;
1785 T.start;
1786 alt {
1787 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1788 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1789 }
1790 [] T.timeout {
1791 setverdict(pass);
1792 }
1793 }
1794
1795 setverdict(pass);
1796}
1797testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1798 var BSSGP_ConnHdlr vc_conn;
1799 f_init();
1800 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1801 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001802 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001803}
1804
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001805/* ATTACH + ATTACH (2nd) */
1806private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1807 g_pars.t_guard := 5.0;
1808
1809 /* first perform regular attach */
1810 f_TC_attach(id);
1811
1812 /* second to perform regular attach */
1813 f_TC_attach(id);
1814}
1815
1816
1817testcase TC_attach_second_attempt() runs on test_CT {
1818 var BSSGP_ConnHdlr vc_conn;
1819 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001820 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001821 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001822 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001823}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001824
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001825private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1826 var Gtp1cUnitdata g_ud;
1827 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1828 var integer seq_nr;
1829
1830 /* first perform regular attach */
1831 f_TC_attach(id);
1832 /* then activate PDP context */
1833 f_pdp_ctx_act(apars);
1834
1835 /* Wait to receive first echo request and send initial Restart counter */
1836 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1837 BSSGP[0].clear;
1838 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1839 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1840 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1841 }
1842
1843 /* At some point next echo request not answered will timeout and SGSN
1844 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1845 timer T := 3.0 * 6.0 + 16.0;
1846 T.start;
1847 alt {
1848 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1849 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1850 setverdict(pass);
1851 }
1852 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1853 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1854 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1855 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1856 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1857 repeat;
1858 }
1859 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1860 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1861 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1862 repeat;
1863 }
1864 [] T.timeout {
1865 setverdict(fail, "BSSGP DeactPdpReq not received");
1866 mtc.stop;
1867 }
1868 [] as_xid(apars);
1869 }
1870 T.stop
1871
1872 setverdict(pass);
1873}
1874/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1875testcase TC_attach_echo_timeout() runs on test_CT {
1876 var BSSGP_ConnHdlr vc_conn;
1877 g_use_echo := true;
1878 f_init();
1879 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1880 vc_conn.done;
1881 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001882 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001883}
1884
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001885private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001886 var Gtp1cUnitdata g_ud;
1887 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1888
1889 /* first perform regular attach */
1890 f_TC_attach(id);
1891 /* Activate a pdp context against the GGSN */
1892 f_pdp_ctx_act(apars);
1893 /* Wait to receive first echo request and send initial Restart counter */
1894 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1895 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1896 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1897 }
1898 /* Wait to receive second echo request and send incremented Restart
1899 counter. This will fake a restarted GGSN, and pdp ctx allocated
1900 should be released by SGSN */
1901 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1902 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1903 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1904 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1905 }
1906 var OCT1 cause_network_failure := int2oct(38, 1)
1907 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001908 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001909 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001910 setverdict(pass);
1911 }
1912 [] as_xid(apars);
1913 }
1914 setverdict(pass);
1915}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001916/* ATTACH + trigger Recovery procedure through EchoResp */
1917testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001918 var BSSGP_ConnHdlr vc_conn;
1919 g_use_echo := true
1920 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001921 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 +02001922 vc_conn.done;
1923 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001924 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001925}
1926
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001927private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1928 var Gtp1cUnitdata g_ud;
1929 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1930 var integer seq_nr := 23;
1931 var GtpPeer peer;
1932 /* first perform regular attach */
1933 f_TC_attach(id);
1934
1935 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1936 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1937 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1938 f_pdp_ctx_act(apars, true);
1939
1940 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1941/* received. */
1942 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1943
1944 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1945 would be great to have an active pdp context here before triggering
1946 Recovery, and making sure the the DEACT request is sent by the SGSN.
1947 */
1948
1949 /* Activate a pdp context against the GGSN, send incremented Recovery
1950 IE. This should trigger the recovery path, but still this specific
1951 CTX activation should work. */
1952 apars.exp_rej_cause := omit; /* default value for tests */
1953 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1954 f_pdp_ctx_act(apars, true);
1955
1956 setverdict(pass);
1957}
1958/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1959testcase TC_attach_restart_ctr_create() runs on test_CT {
1960 var BSSGP_ConnHdlr vc_conn;
1961 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001962 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 +02001963 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001964 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001965}
1966
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001967/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1968private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1969 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1970 var integer seq_nr := 23;
1971 var GtpPeer peer;
1972 var integer i;
1973
1974 /* first perform regular attach */
1975 f_TC_attach(id);
1976 /* then activate PDP context */
1977 f_pdp_ctx_act(apars);
1978
Alexander Couzens0e510e62018-07-28 23:06:00 +02001979 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001980 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1981 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1982
1983 for (i := 0; i < 5; i := i+1) {
1984 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001985 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001986 [] as_xid(apars);
1987 }
1988 }
1989
1990 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1991
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001992 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001993 setverdict(pass);
1994}
1995testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1996 var BSSGP_ConnHdlr vc_conn;
1997 f_init();
1998 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001999 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 +02002000 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002001 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002002}
2003
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002004/* ATTACH + PDP CTX ACT dropped + retrans */
2005private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2006 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2007 var Gtp1cUnitdata g_ud_first, g_ud_second;
2008 /* first perform regular attach */
2009 f_TC_attach(id);
2010
2011 /* then activate PDP context on the Gb side */
2012 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2013 apars.apn, apars.pco), 0);
2014
2015 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2016 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2017 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2018 if (g_ud_first != g_ud_second) {
2019 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2020 mtc.stop;
2021 }
2022 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2023 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2024 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2025 apars.sgsn_tei_c, apars.gtp_resp_cause,
2026 apars.ggsn_tei_c, apars.ggsn_tei_u,
2027 apars.nsapi,
2028 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2029 omit, omit));
2030 }
Harald Welte955aa942019-05-03 01:29:29 +02002031 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002032
2033 /* Now the same with Deact */
2034 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2035 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2036 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2037 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2038 if (g_ud_first != g_ud_second) {
2039 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2040 mtc.stop;
2041 }
2042 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2043 BSSGP[0].clear;
2044 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2045 }
2046 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002047 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002048 setverdict(pass);
2049 }
2050 [] as_xid(apars, 0);
2051 }
2052
2053 setverdict(pass);
2054}
2055testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2056 var BSSGP_ConnHdlr vc_conn;
2057 f_init();
2058 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2059 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002060 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002061}
2062
2063/* Test that SGSN GTP response retransmit queue works fine */
2064private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2065 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2066 var integer seq_nr := 23;
2067 var Gtp1cUnitdata g_ud_first, g_ud_second;
2068 var template Gtp1cUnitdata g_delete_req;
2069 /* first perform regular attach + PDP context act */
2070 f_TC_attach(id);
2071 f_pdp_ctx_act(apars);
2072
2073 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2074 BSSGP[0].clear;
2075 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2076 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2077 GTP.send(g_delete_req);
2078 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002079 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002080 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2081 }
2082 [] as_xid(apars, 0);
2083 }
2084 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2085 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2086 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2087 mtc.stop;
2088 }
2089 };
2090
2091 /* Send duplicate DeleteCtxReq */
2092 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2093 GTP.send(g_delete_req);
2094 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2095 if (g_ud_first != g_ud_second) {
2096 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2097 mtc.stop;
2098 }
2099 }
2100
2101 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2102 * is handled differently by SGSN (expect "non-existent" cause) */
2103 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2104 GTP.send(g_delete_req);
2105 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2106 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2107 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2108 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2109 mtc.stop;
2110 }
2111 }
2112
2113 setverdict(pass);
2114}
2115testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2116 var BSSGP_ConnHdlr vc_conn;
2117 f_init();
2118 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2119 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002120 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002121}
2122
Alexander Couzens5e307b42018-05-22 18:12:20 +02002123private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2124 /* MS: perform regular attach */
2125 f_TC_attach(id);
2126
2127 /* HLR: cancel the location request */
2128 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2129 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002130
2131 /* ensure no Detach Request got received */
2132 timer T := 5.0;
2133 T.start;
2134 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002135 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002136 T.stop;
2137 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002138 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002139 }
2140 [] T.timeout {
2141 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002142 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002143 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002144 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002145 repeat;
2146 }
2147 }
2148}
2149
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002150/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2151private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2152 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2153
2154 /* first perform regular attach */
2155 f_TC_attach(id);
2156 /* then activate PDP context */
2157 f_pdp_ctx_act(apars);
2158 /* then transceive a downlink PDU */
2159 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2160
2161 /* Send Error indication as response from upload PDU and expect deact towards MS */
2162 f_pdp_ctx_deact_mt(apars, true);
2163}
2164testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2165 var BSSGP_ConnHdlr vc_conn;
2166 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002167 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 +02002168 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002169 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002170}
2171
Alexander Couzens5e307b42018-05-22 18:12:20 +02002172testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2173 /* MS <-> SGSN: GMM Attach
2174 * HLR -> SGSN: Cancel Location Request
2175 * HLR <- SGSN: Cancel Location Ack
2176 */
2177 var BSSGP_ConnHdlr vc_conn;
2178 f_init();
2179 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002180 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002181 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002182 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002183}
2184
2185
Alexander Couzensc87967a2018-05-22 16:09:54 +02002186private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2187 /* MS: perform regular attach */
2188 f_TC_attach(id);
2189
2190 /* HLR: cancel the location request */
2191 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2192 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2193 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2194
2195 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002196 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002197 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002198
2199 setverdict(pass);
2200}
2201
2202testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2203 /* MS <-> SGSN: GMM Attach
2204 * HLR -> SGSN: Cancel Location Request
2205 * HLR <- SGSN: Cancel Location Ack
2206 * MS <- SGSN: Detach Request
2207 * SGSN-> MS: Detach Complete
2208 */
2209 var BSSGP_ConnHdlr vc_conn;
2210 f_init();
2211 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002212 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002213 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002214 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002215}
2216
2217
Alexander Couzens6c47f292018-05-22 17:09:49 +02002218private function f_hlr_location_cancel_request_unknown_subscriber(
2219 charstring id,
2220 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2221
2222 /* HLR: cancel the location request */
2223 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2224
2225 /* cause 2 = IMSI_UNKNOWN */
2226 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2227
2228 setverdict(pass);
2229}
2230
2231private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002232 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002233}
2234
2235testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2236 /* HLR -> SGSN: Cancel Location Request
2237 * HLR <- SGSN: Cancel Location Error
2238 */
2239
2240 var BSSGP_ConnHdlr vc_conn;
2241 f_init();
2242 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002243 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 +02002244 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002245 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002246}
2247
2248private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002249 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002250}
2251
2252testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2253 /* HLR -> SGSN: Cancel Location Request
2254 * HLR <- SGSN: Cancel Location Error
2255 */
2256
2257 var BSSGP_ConnHdlr vc_conn;
2258 f_init();
2259 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002260 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 +02002261 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002262 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002263}
2264
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002265private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2266 f_TC_attach(id);
2267 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2268}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002269
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002270testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2271 /* MS <-> SGSN: Attach
2272 * MS -> SGSN: Detach Req (Power off)
2273 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2274 */
2275 var BSSGP_ConnHdlr vc_conn;
2276 var integer id := 33;
2277 var charstring imsi := hex2str(f_gen_imsi(id));
2278
2279 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002280 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002281 vc_conn.done;
2282
2283 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002284 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002285}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002286
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002287/* Attempt an attach, but loose the Identification Request (IMEI) */
2288private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2289 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002290 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002291
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002292 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 +02002293
2294 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002295 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002296 /* break */
2297 }
Harald Welte955aa942019-05-03 01:29:29 +02002298 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002299 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002300 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002301 repeat;
2302 }
Harald Welte955aa942019-05-03 01:29:29 +02002303 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002304 /* ignore ID REQ IMEI */
2305 count_req := count_req + 1;
2306 repeat;
2307 }
2308 }
2309 if (count_req != 5) {
2310 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002311 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002312 }
2313 setverdict(pass);
2314}
2315
2316testcase TC_attach_no_imei_response() runs on test_CT {
2317 /* MS -> SGSN: Attach Request IMSI
2318 * MS <- SGSN: Identity Request IMSI (optional)
2319 * MS -> SGSN: Identity Response IMSI (optional)
2320 * MS <- SGSN: Identity Request IMEI
2321 * MS -x SGSN: no response
2322 * MS <- SGSN: re-send: Identity Request IMEI 4x
2323 * MS <- SGSN: Attach Reject
2324 */
2325 var BSSGP_ConnHdlr vc_conn;
2326 f_init();
2327 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002328 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 +02002329 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002330 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002331}
2332
Alexander Couzens53f20562018-06-12 16:24:12 +02002333/* Attempt an attach, but loose the Identification Request (IMSI) */
2334private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2335 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002336 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002337
2338 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2339 g_pars.p_tmsi := 'c0000035'O;
2340
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002341 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 +02002342
2343 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002344 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002345 /* break */
2346 }
Harald Welte955aa942019-05-03 01:29:29 +02002347 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002348 /* ignore ID REQ IMSI */
2349 count_req := count_req + 1;
2350 repeat;
2351 }
Harald Welte955aa942019-05-03 01:29:29 +02002352 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002353 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002354 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002355 repeat;
2356 }
2357 }
2358 if (count_req != 5) {
2359 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002360 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002361 }
2362 setverdict(pass);
2363}
2364
2365testcase TC_attach_no_imsi_response() runs on test_CT {
2366 /* MS -> SGSN: Attach Request TMSI (unknown)
2367 * MS <- SGSN: Identity Request IMEI (optional)
2368 * MS -> SGSN: Identity Response IMEI (optional)
2369 * MS <- SGSN: Identity Request IMSI
2370 * MS -x SGSN: no response
2371 * MS <- SGSN: re-send: Identity Request IMSI 4x
2372 * MS <- SGSN: Attach Reject
2373 */
2374 var BSSGP_ConnHdlr vc_conn;
2375 f_init();
2376 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002377 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 +02002378 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002379 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002380}
2381
Alexander Couzenscf818962018-06-05 18:00:00 +02002382private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2383 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2384}
2385
2386testcase TC_attach_check_subscriber_list() runs on test_CT {
2387 /* MS <-> SGSN: Attach
2388 * VTY -> SGSN: Check if MS is in subscriber cache
2389 */
2390 var BSSGP_ConnHdlr vc_conn;
2391 var integer id := 34;
2392 var charstring imsi := hex2str(f_gen_imsi(id));
2393
2394 f_init();
2395 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002396 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002397 vc_conn.done;
2398
2399 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2400 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002401 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002402}
2403
Alexander Couzensf9858652018-06-07 16:14:53 +02002404private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2405 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002406 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002407
2408 /* unregister the old IMSI */
2409 f_bssgp_client_unregister(g_pars.imsi);
2410 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002411 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002412 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002413
2414 /* there is no auth */
2415 g_pars.net.expect_auth := false;
2416
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002417 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002418 f_gmm_auth();
2419 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002420 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002421 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002422 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002423 }
Harald Welte955aa942019-05-03 01:29:29 +02002424 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2425 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002426 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002427 setverdict(pass);
2428 }
2429 }
2430}
Alexander Couzens03d12242018-08-07 16:13:52 +02002431
2432private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2433
2434 f_TC_attach_closed_foreign(id);
2435 f_TC_attach_closed_imsi_added(id);
2436
2437}
2438
2439
Alexander Couzensf9858652018-06-07 16:14:53 +02002440testcase TC_attach_closed_add_vty() runs on test_CT {
2441 /* VTY-> SGSN: policy close
2442 * MS -> SGSN: Attach Request
2443 * MS <- SGSN: Identity Request IMSI
2444 * MS -> SGSN: Identity Response IMSI
2445 * MS <- SGSN: Attach Reject
2446 * VTY-> SGSN: policy imsi-acl add IMSI
2447 * MS -> SGSN: Attach Request
2448 * MS <- SGSN: Identity Request IMSI
2449 * MS -> SGSN: Identity Response IMSI
2450 * MS <- SGSN: Identity Request IMEI
2451 * MS -> SGSN: Identity Response IMEI
2452 * MS <- SGSN: Attach Accept
2453 */
2454 var BSSGP_ConnHdlr vc_conn;
2455 f_init();
2456 f_sleep(1.0);
2457 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2458 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002459 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2460 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002461 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002462 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002463 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002464 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002465}
2466
Alexander Couzens0085bd72018-06-12 19:08:44 +02002467/* Attempt an attach, but never answer a Attach Complete */
2468private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2469 var integer count_req := 0;
2470
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002471 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 +02002472 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002473 /* Expect SGSN to perform LU with HLR */
2474 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002475
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002476 timer T := 10.0;
2477 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002478 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002479 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002480 /* break */
2481 }
Harald Welte955aa942019-05-03 01:29:29 +02002482 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002483 /* ignore */
2484 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002485 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002486 repeat;
2487 }
2488 }
2489 if (count_req != 5) {
2490 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002491 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002492 }
2493 setverdict(pass);
2494}
2495
2496testcase TC_attach_check_complete_resend() runs on test_CT {
2497 /* MS -> SGSN: Attach Request IMSI
2498 * MS <- SGSN: Identity Request *
2499 * MS -> SGSN: Identity Response *
2500 * MS <- SGSN: Attach Complete 5x
2501 */
2502 var BSSGP_ConnHdlr vc_conn;
2503 f_init();
2504 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002505 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 +02002506 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002507 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002508}
2509
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002510friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002511 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002512 var PDU_DTAP_PS_MT mt;
2513 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002514
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002515 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002516 p_tmsi := g_pars.p_tmsi;
2517 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002518 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002519 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 +02002520 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002521 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2522 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2523 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002524 setverdict(pass);
2525 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002526 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2527 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2528 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002529 setverdict(pass);
2530 }
2531
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002532 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002533 setverdict(fail, "Unexpected RAU Reject");
2534 mtc.stop;
2535 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002536 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002537 setverdict(fail, "Unexpected RAU Reject");
2538 mtc.stop;
2539 }
2540
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002541 [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 +02002542 key_sts := ?)) {
2543 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2544 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002545 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002546 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002547 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002548 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2549 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002550 }
2551}
2552
Alexander Couzensbfda9212018-07-31 03:17:33 +02002553private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002554 /* first perform regular attach */
2555 f_TC_attach(id);
2556
2557 /* then send RAU */
2558 f_routing_area_update(g_pars.ra);
2559
2560 /* do another RAU */
2561 f_routing_area_update(g_pars.ra);
2562
2563 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2564}
2565
2566testcase TC_attach_rau_a_a() runs on test_CT {
2567 /* MS <-> SGSN: Successful Attach
2568 * MS -> SGSN: Routing Area Update Request
2569 * MS <- SGSN: Routing Area Update Accept
2570 * MS -> SGSN: Routing Area Update Request
2571 * MS <- SGSN: Routing Area Update Accept
2572 * MS -> SGSN: Detach (PowerOff)
2573 */
2574 var BSSGP_ConnHdlr vc_conn;
2575 f_init();
2576 f_sleep(1.0);
2577 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2578 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002579 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002580}
2581
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002582private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002583 f_TC_attach(id);
2584
2585 log("attach complete sending rau");
2586 f_routing_area_update(g_pars.ra, 0);
2587
2588 log("rau complete unregistering");
2589 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002590 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002591
2592 log("sending second RAU via different RA");
2593 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2594
2595 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2596}
2597
2598testcase TC_attach_rau_a_b() runs on test_CT {
2599 /* MS <-> SGSN: Successful Attach
2600 * MS -> SGSN: Routing Area _a_ Update Request
2601 * MS <- SGSN: Routing Area _a_ Update Accept
2602 * MS -> SGSN: Routing Area _b_ Update Request
2603 * MS <- SGSN: Routing Area _b_ Update Accept
2604 * MS -> SGSN: Detach (PowerOff)
2605 */
2606 var BSSGP_ConnHdlr vc_conn;
2607 f_init();
2608 f_sleep(1.0);
2609 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2610 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002611 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002612}
2613
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002614private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2615 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002616 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002617 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002618 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002619
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002620 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002621
2622 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002623 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002624 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2625 mtc.stop;
2626 }
Harald Welte955aa942019-05-03 01:29:29 +02002627 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002628 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002629 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002630 repeat;
2631 }
Harald Welte955aa942019-05-03 01:29:29 +02002632 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002633 /* send out a second GMM_Attach Request.
2634 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2635 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002636 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002637 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002638 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002639 }
2640 }
2641 f_sleep(1.0);
2642
2643 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2644 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002645 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002646 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002647 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002648 repeat;
2649 }
Harald Welte955aa942019-05-03 01:29:29 +02002650 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002651 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2652 mtc.stop;
2653 }
Harald Welte955aa942019-05-03 01:29:29 +02002654 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002655 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2656 mtc.stop;
2657 }
Harald Welte955aa942019-05-03 01:29:29 +02002658 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2659 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002660 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002661 setverdict(pass);
2662 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2663 }
2664 }
2665}
2666
2667testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2668 /* Testing if the SGSN ignore Attach Request with the exact same content */
2669 /* MS -> SGSN: Attach Request IMSI
2670 * MS <- SGSN: Identity Request IMSI (optional)
2671 * MS -> SGSN: Identity Response IMSI (optional)
2672 * MS <- SGSN: Identity Request IMEI
2673 * MS -> SGSN: Attach Request (2nd)
2674 * MS <- SGSN: Identity Response IMEI
2675 * MS <- SGSN: Attach Accept
2676 * MS -> SGSN: Attach Complete
2677 */
2678 var BSSGP_ConnHdlr vc_conn;
2679 f_init();
2680 f_sleep(1.0);
2681 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2682 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2683 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002684 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002685}
2686
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002687private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002688 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2689
2690 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2691
2692 /* send Attach Request */
2693 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2694 * 3G auth vectors */
2695 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2696 /* The thing is, if the solSACapability is 'omit', then the
2697 * revisionLevelIndicatior is at the wrong place! */
2698 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002699 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002700
2701 /* do the auth */
2702 var PDU_L3_MS_SGSN l3_mo;
2703 var PDU_L3_SGSN_MS l3_mt;
2704 var default di := activate(as_mm_identity());
2705
2706 var GSUP_IE auth_tuple;
2707 var template AuthenticationParameterAUTNTLV autn;
2708
2709 g_pars.vec := f_gen_auth_vec_3g();
2710 autn := {
2711 elementIdentifier := '28'O,
2712 lengthIndicator := lengthof(g_pars.vec.autn),
2713 autnValue := g_pars.vec.autn
2714 };
2715 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2716 g_pars.vec.sres,
2717 g_pars.vec.kc,
2718 g_pars.vec.ik,
2719 g_pars.vec.ck,
2720 g_pars.vec.autn,
2721 g_pars.vec.res));
2722 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2723 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2724 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2725
2726 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2727 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002728 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002729
2730 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002731 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002732
2733 /* wait for the GSUP resync request */
2734 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2735 g_pars.imsi,
2736 g_pars.vec.auts,
2737 g_pars.vec.rand));
2738
2739 /* generate new key material */
2740 g_pars.vec := f_gen_auth_vec_3g();
2741 autn := {
2742 elementIdentifier := '28'O,
2743 lengthIndicator := lengthof(g_pars.vec.autn),
2744 autnValue := g_pars.vec.autn
2745 };
2746
2747 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2748 g_pars.vec.sres,
2749 g_pars.vec.kc,
2750 g_pars.vec.ik,
2751 g_pars.vec.ck,
2752 g_pars.vec.autn,
2753 g_pars.vec.res));
2754 /* send new key material */
2755 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2756
2757 /* wait for the new Auth Request */
2758 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2759 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002760 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002761 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2762 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2763 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2764 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2765 valueField := substr(g_pars.vec.res, 0, 4)
2766 };
2767 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2768 elementIdentifier := '21'O,
2769 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2770 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2771 };
2772 l3_mo := valueof(auth_ciph_resp);
2773 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2774 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2775 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2776 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2777 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002778 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002779 deactivate(di);
2780
2781 /* Expect SGSN to perform LU with HLR */
2782 f_gmm_gsup_lu_isd();
2783
Harald Welte955aa942019-05-03 01:29:29 +02002784 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2785 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002786 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002787 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002788 setverdict(pass);
2789}
2790
2791testcase TC_attach_usim_resync() runs on test_CT {
2792 /* MS -> SGSN: Attach Request
2793 * MS <- SGSN: Identity Request IMSI
2794 * MS -> SGSN: Identity Response IMSI
2795 * MS <- SGSN: Identity Request IMEI
2796 * MS -> SGSN: Identity Response IMEI
2797 * HLR<- SGSN: SAI Request
2798 * HLR-> SGSN: SAI Response
2799 * MS <- SGSN: Auth Request
2800 * MS -> SGSN: Auth Failure (with AUTS)
2801 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2802 * HLR-> SGSN: SAI Response (new key material)
2803 * MS <- SGSN: Auth Request (new key material)
2804 * MS -> SGSN: Auth Response
2805 * MS <- SGSN: Attach Accept
2806 * MS -> SGSN: Attach Complete
2807 */
2808 var BSSGP_ConnHdlr vc_conn;
2809 f_init();
2810 f_sleep(1.0);
2811 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2812 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002813 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002814}
2815
Harald Weltea05b8072019-04-23 22:35:05 +02002816
2817/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2818private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2819 f_gmm_attach(false, false);
2820 f_sleep(1.0);
2821 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2822 /* try to detach to check if SGSN is still alive */
2823 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2824}
2825testcase TC_llc_null() runs on test_CT {
2826 var BSSGP_ConnHdlr vc_conn;
2827 f_init();
2828 f_sleep(1.0);
2829 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2830 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002831 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002832}
2833
Harald Welte645a1512019-04-23 23:18:23 +02002834/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2835private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2836 f_gmm_attach(false, false);
2837 f_sleep(1.0);
2838 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002839 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002840 setverdict(pass);
2841}
2842testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2843 var BSSGP_ConnHdlr vc_conn;
2844 f_init();
2845 f_sleep(1.0);
2846 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2847 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002848 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002849}
2850
2851/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2852private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2853 f_gmm_attach(false, false);
2854 f_sleep(1.0);
2855 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002856 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002857 setverdict(pass);
2858}
2859testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2860 var BSSGP_ConnHdlr vc_conn;
2861 f_init();
2862 f_sleep(1.0);
2863 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2864 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002865 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002866}
2867
Harald Welte2aaac1b2019-05-02 10:02:53 +02002868/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2869private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2870 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2871 var template (value) XID_Information xid;
2872 var template XID_Information xid_rx;
2873
2874 /* first perform regular attach */
2875 f_TC_attach(id);
2876 /* then activate PDP context */
2877 f_pdp_ctx_act(apars);
2878
2879 /* start MO XID */
2880 xid := { ts_XID_L3(''O) };
2881 xid_rx := { tr_XID_L3(''O) };
2882 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2883 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002884 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002885 [] as_xid(apars);
2886 }
2887 setverdict(pass);
2888}
2889testcase TC_xid_empty_l3() runs on test_CT {
2890 var BSSGP_ConnHdlr vc_conn;
2891 f_init();
2892 f_sleep(1.0);
2893 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2894 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002895 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002896}
2897
2898private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2899 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2900 var template (value) XID_Information xid;
2901 var template XID_Information xid_rx;
2902
2903 /* first perform regular attach */
2904 f_TC_attach(id);
2905 /* then activate PDP context */
2906 f_pdp_ctx_act(apars);
2907
2908 /* start MO XID */
2909 xid := { ts_XID_N201U(1234) };
2910 xid_rx := { tr_XID_N201U(1234) };
2911 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2912 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002913 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002914 [] as_xid(apars);
2915 }
2916 setverdict(pass);
2917}
2918testcase TC_xid_n201u() runs on test_CT {
2919 var BSSGP_ConnHdlr vc_conn;
2920 f_init();
2921 f_sleep(1.0);
2922 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2923 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002924 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002925}
2926
Alexander Couzens6bee0872019-05-11 01:48:50 +02002927private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2928 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2929
2930 /* first perform regular attach */
2931 f_TC_attach(id);
2932 /* then activate PDP context */
2933 f_pdp_ctx_act(apars);
2934 /* do a normal detach */
2935 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2936}
2937
2938testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2939 /* MS -> SGSN: Attach Request
2940 * MS <-> SGSN: [..]
2941 * MS -> SGSN: Attach Complete
2942 * MS -> SGSN: PDP Activate Request
2943 * MS <- SGSN: PDP Activate Accept
2944 * MS -> SGSN: GMM Detach Request
2945 * MS <- SGSN: GMM Detach Accept
2946 */
2947 var BSSGP_ConnHdlr vc_conn;
2948 f_init();
2949 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2950 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002951 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002952}
Harald Welte645a1512019-04-23 23:18:23 +02002953
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002954private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2955 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2956 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2957 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2958 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2959 var PDU_L3_SGSN_MS l3_mt;
2960
2961 f_send_l3(attach_req, 0);
2962
2963 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2964
2965 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2966 alt {
2967 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2968 setverdict(pass);
2969 }
2970 [] BSSGP[0].receive { repeat; }
2971 }
2972}
2973
2974/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2975 * See OS#3957 and OS#4245 for more information.
2976 */
2977testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2978 /*
2979 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2980 * MS <-- SGSN: Identity Request (IMEI)
2981 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2982 */
2983 var BSSGP_ConnHdlr vc_conn;
2984 f_init();
2985 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2986 vc_conn.done;
2987 f_cleanup();
2988}
2989
Harald Welte8e5932e2020-06-17 22:12:54 +02002990private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2991var PDU_BSSGP rx;
2992[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2993 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2994 mtc.stop;
2995 }
2996}
2997
2998/* SUSPEND, then DL traffic: should not pass + no paging expected */
2999private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3000 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3001 var default d;
3002
3003 /* first perform regular attach */
3004 f_TC_attach(id);
3005 /* then activate PDP context */
3006 f_pdp_ctx_act(apars);
3007 /* then transceive a downlink PDU */
3008 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3009
3010 /* now suspend GPRS */
3011 f_bssgp_suspend();
3012
3013 d := activate(as_nopaging_ps());
3014
3015 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3016 * nor any related paging requests */
3017 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3018
3019 deactivate(d);
3020}
3021testcase TC_suspend_nopaging() runs on test_CT {
3022 var BSSGP_ConnHdlr vc_conn;
3023 f_init();
3024 f_sleep(1.0);
3025 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3026 vc_conn.done;
3027 f_cleanup();
3028}
3029
3030
3031/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3032private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3033 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3034 var OCT1 susp_ref;
3035 var default d;
3036
3037 /* first perform regular attach */
3038 f_TC_attach(id);
3039 /* then activate PDP context */
3040 f_pdp_ctx_act(apars);
3041 /* then transceive a downlink PDU */
3042 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3043
3044 /* now suspend GPRS */
3045 susp_ref := f_bssgp_suspend();
3046
3047 d := activate(as_nopaging_ps());
3048
3049 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3050 * nor any related paging requests */
3051 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3052
3053 deactivate(d);
3054
3055 /* resume GPRS */
3056 f_bssgp_resume(susp_ref);
3057
3058 /* now data should be flowing again */
3059 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3060}
3061testcase TC_suspend_resume() runs on test_CT {
3062 var BSSGP_ConnHdlr vc_conn;
3063 f_init();
3064 f_sleep(1.0);
3065 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3066 vc_conn.done;
3067 f_cleanup();
3068}
3069
3070/* SUSPEND, then RAU: data expected to flow after implicit resume */
3071private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3072 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3073 var default d;
3074
3075 /* first perform regular attach */
3076 f_TC_attach(id);
3077 /* then activate PDP context */
3078 f_pdp_ctx_act(apars);
3079 /* then transceive a downlink PDU */
3080 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3081
3082 /* now suspend GPRS */
3083 f_bssgp_suspend();
3084
3085 d := activate(as_nopaging_ps());
3086
3087 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3088 * nor any related paging requests */
3089 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3090
3091 deactivate(d);
3092
3093 /* perform RAU (implicit RESUME) */
3094 f_routing_area_update(g_pars.ra);
3095
3096 /* now data should be flowing again */
3097 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3098
3099}
3100testcase TC_suspend_rau() runs on test_CT {
3101 var BSSGP_ConnHdlr vc_conn;
3102 f_init();
3103 f_sleep(1.0);
3104 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3105 vc_conn.done;
3106 f_cleanup();
3107}
3108
3109
3110/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3111private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3112 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3113 var default d;
3114
3115 /* first perform regular attach */
3116 f_TC_attach(id);
3117 /* then activate PDP context */
3118 f_pdp_ctx_act(apars);
3119 /* then transceive a downlink PDU */
3120 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3121
3122 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3123 f_sleep(5.0);
3124
3125 /* now data should be flowing again, but with PS PAGING */
3126 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3127 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3128
3129 /* FIXME: simulate paging response */
3130 /* FIXME: verify PDU actually arrives only after paging response was successful */
3131
3132}
3133testcase TC_paging_ps() runs on test_CT {
3134 var BSSGP_ConnHdlr vc_conn;
3135 f_init();
3136 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3137 f_sleep(1.0);
3138 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3139 vc_conn.done;
3140 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3141 f_cleanup();
3142}
3143
Philipp Maier7df55e02020-12-14 23:46:04 +01003144private function f_TC_bssgp_rim_dummy(charstring id) runs on BSSGP_ConnHdlr {
3145}
3146
3147/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3148 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3149 * other and vice versa. */
3150testcase TC_bssgp_rim_single_report() runs on test_CT {
3151 var BSSGP_ConnHdlr vc_conn;
3152 f_init();
3153 vc_conn := f_start_handler(refers(f_TC_bssgp_rim_dummy), testcasename(), g_gb, 17);
3154 vc_conn.done;
3155
3156 timer T := 2.0;
3157
3158 var template RIM_Routing_Address dst_addr;
3159 var template RIM_Routing_Address src_addr;
3160 var template RAN_Information_Request_RIM_Container req_cont;
3161 var template RAN_Information_RIM_Container res_cont;
3162 var template PDU_BSSGP bssgp_rim_pdu;
3163 var template PDU_BSSGP bssgp_rim_pdu_expect;
3164
3165 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3166 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003167
3168
Philipp Maier7df55e02020-12-14 23:46:04 +01003169 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3170 * based on the cell id in dst_addr to GB interface #1. */
3171 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3172 ts_RIM_Sequence_Number(1),
3173 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3174 ts_RIM_Protocol_Version_Number(1),
3175 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3176 omit);
3177 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3178 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3179 req_cont);
3180 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3181 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3182 tr_RAN_Information_Request_RIM_Container);
3183 RIM[0].send(bssgp_rim_pdu);
3184 T.start;
3185 alt {
3186 [] RIM[1].receive(bssgp_rim_pdu_expect) { }
3187 [] RIM[1].receive {
3188 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3189 }
3190 [] T.timeout {
3191 setverdict(fail, "No BSSGP RIM PDU received");
3192 mtc.stop;
3193 }
3194 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003195
Philipp Maier7df55e02020-12-14 23:46:04 +01003196 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3197 * GB interface #0 */
3198 var octetstring si1 := '198fb100000000000000000000000000007900002b'O;
3199 var octetstring si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
3200 var octetstring si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
3201 var octetstring si := si1 & si3 & si13;
3202
3203 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3204 ts_RIM_Sequence_Number(2),
3205 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3206 ts_RIM_Protocol_Version_Number(1),
3207 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si)),
3208 omit);
3209 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3210 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3211 res_cont);
3212 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3213 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3214 ?);
3215 RIM[1].send(bssgp_rim_pdu);
3216 T.start;
3217 alt {
3218 [] RIM[0].receive(bssgp_rim_pdu_expect) { }
3219 [] RIM[0].receive {
3220 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3221 }
3222 [] T.timeout {
3223 setverdict(fail, "No BSSGP RIM PDU received");
3224 mtc.stop;
3225 }
3226 }
3227
3228 f_cleanup();
3229}
Harald Welte8e5932e2020-06-17 22:12:54 +02003230
Harald Welte5ac31492018-02-15 20:39:13 +01003231control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003232 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003233 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003234 execute( TC_attach_umts_aka_umts_res() );
3235 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003236 execute( TC_attach_auth_id_timeout() );
3237 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003238 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003239 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003240 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003241 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003242 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003243 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003244 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003245 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003246 execute( TC_attach_closed_add_vty(), 20.0 );
3247 execute( TC_attach_check_subscriber_list(), 20.0 );
3248 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003249 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003250 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3251 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3252 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3253 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003254 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003255 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003256 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003257 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003258 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003259 execute( TC_detach_unknown_nopoweroff() );
3260 execute( TC_detach_unknown_poweroff() );
3261 execute( TC_detach_nopoweroff() );
3262 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003263 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003264 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003265 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003266 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003267 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003268 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003269 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003270 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003271 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003272 execute( TC_attach_restart_ctr_echo() );
3273 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003274 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003275 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3276 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003277 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003278 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003279 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003280
Harald Welte2aaac1b2019-05-02 10:02:53 +02003281 execute( TC_xid_empty_l3() );
3282 execute( TC_xid_n201u() );
3283
Harald Weltea05b8072019-04-23 22:35:05 +02003284 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003285 execute( TC_llc_sabm_dm_llgmm() );
3286 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003287
Harald Welte8e5932e2020-06-17 22:12:54 +02003288 execute( TC_suspend_nopaging() );
3289 execute( TC_suspend_resume() );
3290 execute( TC_suspend_rau() );
3291 execute( TC_paging_ps() );
3292
Philipp Maier7df55e02020-12-14 23:46:04 +01003293 execute( TC_bssgp_rim_single_report() );
3294
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003295 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3296 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003297}
Harald Welte96a33b02018-02-04 10:36:22 +01003298
3299
3300
3301}