blob: 57c9e0255e6a06b595e3ccd03c1defce3a403fbc [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;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010018import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010019import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010023import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020024import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010025
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from GSUP_Emulation all;
33import from GSUP_Types all;
34import from IPA_Emulation all;
35
Harald Welte26fbb6e2019-04-14 17:32:46 +020036import from RAN_Adapter all;
37import from RAN_Emulation all;
38import from RANAP_Templates all;
39import from RANAP_PDU_Descriptions all;
40import from RANAP_IEs all;
41
Harald Welteeded9ad2018-02-17 20:57:34 +010042import from GTP_Emulation all;
43import from GTP_Templates all;
44import from GTP_CodecPort all;
45import from GTPC_Types all;
46import from GTPU_Types all;
47
Harald Weltea2526a82018-02-18 19:03:36 +010048import from LLC_Types all;
49import from LLC_Templates all;
50
51import from SNDCP_Types all;
52
Harald Weltebd194722018-02-16 22:11:08 +010053import from TELNETasp_PortType all;
54import from Osmocom_VTY_Functions all;
55
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010056import from GSM_RR_Types all;
57
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020058import from MobileL3_MM_Types all;
59
Harald Welteeded9ad2018-02-17 20:57:34 +010060
Harald Welte5ac31492018-02-15 20:39:13 +010061modulepar {
62 /* IP/port on which we run our internal GSUP/HLR emulation */
63 charstring mp_hlr_ip := "127.0.0.1";
64 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010065 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020066 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020067
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 NSConfigurations mp_nsconfig := {
69 {
70 local_udp_port := 21010,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 96,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21011,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 97,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 },
89 {
90 local_udp_port := 21012,
91 local_ip := "127.0.0.1",
92 remote_udp_port := 23000,
93 remote_ip := "127.0.0.1",
94 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020095 nsei := 98,
96 role_sgsn := false,
97 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020098 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020099 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200100
101 RAN_Configurations mp_ranap_cfg := {
102 {
103 transport := RANAP_TRANSPORT_IuCS,
104 sccp_service_type := "mtp3_itu",
105 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
106 own_pc := 195,
107 own_ssn := 142,
108 peer_pc := 188, /* 0.23.4 */
109 peer_ssn := 142,
110 sio := '83'O,
111 rctx := 2
112 }
113 }
Harald Welte5ac31492018-02-15 20:39:13 +0100114};
115
116type record GbInstance {
117 NS_CT vc_NS,
118 BSSGP_CT vc_BSSGP,
119 BssgpConfig cfg
120};
Harald Welte96a33b02018-02-04 10:36:22 +0100121
Harald Welte2fa771f2019-05-02 20:13:53 +0200122const integer NUM_GB := 3;
123type record length(NUM_GB) of GbInstance GbInstances;
124type record length(NUM_GB) of NSConfiguration NSConfigurations;
125type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200126
Harald Welte26fbb6e2019-04-14 17:32:46 +0200127const integer NUM_RNC := 1;
128type record of RAN_Configuration RAN_Configurations;
129
Harald Welte96a33b02018-02-04 10:36:22 +0100130type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200131 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200132 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200133 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100134
Harald Welte5ac31492018-02-15 20:39:13 +0100135 var GSUP_Emulation_CT vc_GSUP;
136 var IPA_Emulation_CT vc_GSUP_IPA;
137 /* only to get events from IPA underneath GSUP */
138 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100139
Harald Welteeded9ad2018-02-17 20:57:34 +0100140 var GTP_Emulation_CT vc_GTP;
141
Harald Weltebd194722018-02-16 22:11:08 +0100142 port TELNETasp_PT SGSNVTY;
143
Harald Welte96a33b02018-02-04 10:36:22 +0100144 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200145 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100146};
147
Harald Welte26fbb6e2019-04-14 17:32:46 +0200148type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100149 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100150 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200151 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100152}
153
154type record SGSN_ConnHdlrNetworkPars {
155 boolean expect_ptmsi,
156 boolean expect_auth,
157 boolean expect_ciph
158};
159
160type record BSSGP_ConnHdlrPars {
161 /* IMEI of the simulated ME */
162 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200163 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100164 hexstring imsi,
165 /* MSISDN of the simulated MS (probably unused) */
166 hexstring msisdn,
167 /* P-TMSI allocated to the simulated MS */
168 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100169 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100170 /* TLLI of the simulated MS */
171 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100172 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100173 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200174 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200175 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
176 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100177 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100178 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200179 float t_guard,
180 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200181 SCCP_PAR_Address sccp_addr_local optional,
182 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100183};
184
Alexander Couzens89508702018-07-31 04:16:10 +0200185private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200186 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200187 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
188
189 var RoutingAreaIdentificationV ret := {
190 mccDigit1 := mcc_mnc[0],
191 mccDigit2 := mcc_mnc[1],
192 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200193 mncDigit3 := mcc_mnc[3],
194 mncDigit1 := mcc_mnc[4],
195 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200196 lac := int2oct(cell_id.ra_id.lai.lac, 16),
197 rac := int2oct(cell_id.ra_id.rac, 8)
198 }
199 return ret;
200};
201
Alexander Couzens51114d12018-07-31 18:41:56 +0200202private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
203 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
204 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100205 /* connect lower end of BSSGP emulation with NS upper port */
206 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
207 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
208 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
209
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200210 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100211 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
212}
213
214private function f_init_gsup(charstring id) runs on test_CT {
215 id := id & "-GSUP";
216 var GsupOps ops := {
217 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
218 };
219
220 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
221 vc_GSUP := GSUP_Emulation_CT.create(id);
222
223 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
224 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
225 /* we use this hack to get events like ASP_IPA_EVENT_UP */
226 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
227
228 vc_GSUP.start(GSUP_Emulation.main(ops, id));
229 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
230
231 /* wait for incoming connection to GSUP port before proceeding */
232 timer T := 10.0;
233 T.start;
234 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700235 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100236 [] T.timeout {
237 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200238 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100239 }
240 }
241}
242
Harald Welteeded9ad2018-02-17 20:57:34 +0100243private function f_init_gtp(charstring id) runs on test_CT {
244 id := id & "-GTP";
245
246 var GtpEmulationCfg gtp_cfg := {
247 gtpc_bind_ip := mp_ggsn_ip,
248 gtpc_bind_port := GTP1C_PORT,
249 gtpu_bind_ip := mp_ggsn_ip,
250 gtpu_bind_port := GTP1U_PORT,
251 sgsn_role := false
252 };
253
254 vc_GTP := GTP_Emulation_CT.create(id);
255 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
256}
257
Harald Weltebd194722018-02-16 22:11:08 +0100258private function f_init_vty() runs on test_CT {
259 map(self:SGSNVTY, system:SGSNVTY);
260 f_vty_set_prompts(SGSNVTY);
261 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200262 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100263 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
264}
265
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200266private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
267 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200268 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200269 } else {
270 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
271 }
272}
273
Harald Weltebd194722018-02-16 22:11:08 +0100274
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200275/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
276function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200277 var integer i;
278
Harald Welte96a33b02018-02-04 10:36:22 +0100279 if (g_initialized == true) {
280 return;
281 }
282 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100283 g_gb[0].cfg := {
284 nsei := 96,
285 bvci := 196,
286 cell_id := {
287 ra_id := {
288 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100289 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100290 rac := 0
291 },
292 cell_id := 20960
293 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200294 sgsn_role := false,
295 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100296 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200297 g_gb[1].cfg := {
298 nsei := 97,
299 bvci := 210,
300 cell_id := {
301 ra_id := {
302 lai := {
303 mcc_mnc := mcc_mnc, lac := 13200},
304 rac := 0
305 },
306 cell_id := 20961
307 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200308 sgsn_role := false,
309 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200310 };
311 g_gb[2].cfg := {
312 nsei := 98,
313 bvci := 220,
314 cell_id := {
315 ra_id := {
316 lai := {
317 mcc_mnc := mcc_mnc, lac := 13300},
318 rac := 0
319 },
320 cell_id := 20962
321 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200322 sgsn_role := false,
323 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200324 };
Harald Welte96a33b02018-02-04 10:36:22 +0100325
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200326 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200327 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
328 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
329 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200330
Alexander Couzens1552e792019-07-23 20:38:39 +0200331 if (g_ranap_enable) {
332 for (i := 0; i < NUM_RNC; i := i+1) {
333 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
334 f_ran_adapter_start(g_ranap[i]);
335 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200336 }
Harald Welte5ac31492018-02-15 20:39:13 +0100337 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100338 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200339 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100340}
Harald Welte96a33b02018-02-04 10:36:22 +0100341
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200342function f_cleanup() runs on test_CT {
343 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200344 if (g_ranap_enable) {
345 for (i := 0; i < NUM_RNC; i := i+1) {
346 f_ran_adapter_cleanup(g_ranap[i]);
347 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200348 }
349 self.stop;
350}
351
Harald Welte26fbb6e2019-04-14 17:32:46 +0200352private function RncUnitdataCallback(RANAP_PDU ranap)
353runs on RAN_Emulation_CT return template RANAP_PDU {
354 var template RANAP_PDU resp := omit;
355
356 log ("RANAP_RncUnitDataCallback");
357 /* answer all RESET with RESET ACK */
358 if (match(ranap, tr_RANAP_Reset)) {
359 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
360 var CN_DomainIndicator dom;
361 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
362 resp := ts_RANAP_ResetAck(dom);
363 }
364 return resp;
365}
366
367const RanOps RNC_RanOps := {
368 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
369 ranap_unitdata_cb := refers(RncUnitdataCallback),
370 ps_domain := true,
371 decode_dtap := true,
372 role_ms := true,
373 protocol := RAN_PROTOCOL_RANAP,
374 transport := RANAP_TRANSPORT_IuCS,
375 use_osmux := false,
376 sccp_addr_local := omit,
377 sccp_addr_peer := omit
378};
379
Harald Welte5ac31492018-02-15 20:39:13 +0100380type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
381
382/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200383function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100384 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100385runs on test_CT return BSSGP_ConnHdlr {
386 var BSSGP_ConnHdlr vc_conn;
387 var SGSN_ConnHdlrNetworkPars net_pars := {
388 expect_ptmsi := true,
389 expect_auth := true,
390 expect_ciph := false
391 };
392 var BSSGP_ConnHdlrPars pars := {
393 imei := f_gen_imei(imsi_suffix),
394 imsi := f_gen_imsi(imsi_suffix),
395 msisdn := f_gen_msisdn(imsi_suffix),
396 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100397 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100398 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100399 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100400 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200401 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200402 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100403 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100404 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200405 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200406 sccp_addr_local := omit,
407 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100408 };
409
Alexander Couzens1552e792019-07-23 20:38:39 +0200410 if (g_ranap_enable) {
411 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
412 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
413 }
414
Harald Welte5ac31492018-02-15 20:39:13 +0100415 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200416 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200417 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200418 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
419 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200420 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200421 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
422 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200423 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200424 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100425
Harald Welte26fbb6e2019-04-14 17:32:46 +0200426 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200427 if (g_ranap_enable) {
428 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
429 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
430 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200431
Harald Welte5ac31492018-02-15 20:39:13 +0100432 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
433 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
434
Harald Welteeded9ad2018-02-17 20:57:34 +0100435 connect(vc_conn:GTP, vc_GTP:CLIENT);
436 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
437
Harald Welte5ac31492018-02-15 20:39:13 +0100438 vc_conn.start(f_handler_init(fn, id, pars));
439 return vc_conn;
440}
441
Harald Welte62e29582018-02-16 21:17:11 +0100442private altstep as_Tguard() runs on BSSGP_ConnHdlr {
443 [] g_Tguard.timeout {
444 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200445 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100446 }
447}
448
Harald Welte5ac31492018-02-15 20:39:13 +0100449/* first function called in every ConnHdlr */
450private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
451runs on BSSGP_ConnHdlr {
452 /* do some common stuff like setting up g_pars */
453 g_pars := pars;
454
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200455 llc := f_llc_create(false);
456
Harald Welte5ac31492018-02-15 20:39:13 +0100457 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200458 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100459 /* tell GSUP dispatcher to send this IMSI to us */
460 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100461 /* tell GTP dispatcher to send this IMSI to us */
462 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100463
Harald Welte62e29582018-02-16 21:17:11 +0100464 g_Tguard.start(pars.t_guard);
465 activate(as_Tguard());
466
Harald Welte5ac31492018-02-15 20:39:13 +0100467 /* call the user-supplied test case function */
468 fn.apply(id);
469 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100470}
471
472/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100473 * Detach without Attach
474 * SM procedures without attach / RAU
475 * ATTACH / RAU
476 ** with / without authentication
477 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100478 * re-transmissions of LLC frames
479 * PDP Context activation
480 ** with different GGSN config in SGSN VTY
481 ** with different PDP context type (v4/v6/v46)
482 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100483 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100484 */
485
486testcase TC_wait_ns_up() runs on test_CT {
487 f_init();
488 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200489 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100490}
491
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200492friend function is_gb(integer ran_index) return boolean {
493 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200494}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200495friend function is_iu(integer ran_index) return boolean {
496 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200497}
498
Alexander Couzens0507ec32019-09-15 22:41:22 +0200499function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200500 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200501 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 +0200502}
503
Alexander Couzens0507ec32019-09-15 22:41:22 +0200504private 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 +0200505 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
506 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
507 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200508 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200509}
510
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200511/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
512function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
513 log("Sending InitialUE: ", l3_mo);
514 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
515 var RANAP_PDU ranap;
516 var LAI lai := {
517 pLMNidentity := '62F224'O,
518 lAC := '1234'O,
519 iE_Extensions := omit
520 };
521 var SAI sai := {
522 pLMNidentity := lai.pLMNidentity,
523 lAC := lai.lAC,
524 sAC := '0000'O, /* FIXME */
525 iE_Extensions := omit
526 };
527 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
528 var GlobalRNC_ID grnc_id := {
529 pLMNidentity := lai.pLMNidentity,
530 rNC_ID := 2342 /* FIXME */
531 };
532
533 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
534 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
535 alt {
536 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
537 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
538 setverdict(fail, "DISC.ind from SCCP");
539 mtc.stop;
540 }
541 }
542}
543
544/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200545function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
546 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200547 if (g_pars.rnc_send_initial_ue) {
548 g_pars.rnc_send_initial_ue := false;
549 f_send_l3_initial_ue(l3_mo);
550 } else {
551 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
552 }
553 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200554 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200555 }
556}
557
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200558altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700559 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200560 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100561 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200562 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100563 repeat;
564 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200565 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200566 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200567 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200568 repeat;
569 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200570 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100571 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200573 repeat;
574 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200575 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200576 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200577 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100578 repeat;
579 }
580}
Harald Welte96a33b02018-02-04 10:36:22 +0100581
Harald Welteca362462019-05-02 20:11:21 +0200582/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200583function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200584runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200585 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200586 var PDU_L3_SGSN_MS l3_mt;
587 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200588 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
589 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200590 l3_mt := mt.dtap;
591 }
Harald Welteca362462019-05-02 20:11:21 +0200592 }
593 return l3_mt;
594}
595
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200596/* perform GMM authentication (if expected).
597 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
598 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200599function 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 +0100600 var PDU_L3_MS_SGSN l3_mo;
601 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200602 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100603 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200604 var GSUP_IE auth_tuple;
605 var template AuthenticationParameterAUTNTLV autn;
606
607 if (umts_aka_challenge) {
608 g_pars.vec := f_gen_auth_vec_3g();
609 autn := {
610 elementIdentifier := '28'O,
611 lengthIndicator := lengthof(g_pars.vec.autn),
612 autnValue := g_pars.vec.autn
613 };
614
615 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
616 g_pars.vec.sres,
617 g_pars.vec.kc,
618 g_pars.vec.ik,
619 g_pars.vec.ck,
620 g_pars.vec.autn,
621 g_pars.vec.res));
622 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
623 } else {
624 g_pars.vec := f_gen_auth_vec_2g();
625 autn := omit;
626 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
627 g_pars.vec.sres,
628 g_pars.vec.kc));
629 log("GSUP sends only 2G auth tuple", auth_tuple);
630 }
Harald Welteca362462019-05-02 20:11:21 +0200631
Harald Welte5ac31492018-02-15 20:39:13 +0100632 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
633 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200634
635 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
636 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200637 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100638 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200639 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
640
641 if (umts_aka_challenge and not force_gsm_sres) {
642 /* set UMTS response instead */
643 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
644 valueField := substr(g_pars.vec.res, 0, 4)
645 };
646 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
647 elementIdentifier := '21'O,
648 lengthIndicator := lengthof(g_pars.vec.res) - 4,
649 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
650 };
651 }
652
653 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100654 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
655 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
656 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
657 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
658 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200659 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200660
661 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200663 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
664 key_sts := ?)) {
665 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
666 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200667 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200668 }
669 }
Harald Welte76dee092018-02-16 22:12:59 +0100670 } else {
671 /* wait for identity procedure */
672 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100673 }
Harald Welte76dee092018-02-16 22:12:59 +0100674
Harald Welte5ac31492018-02-15 20:39:13 +0100675 deactivate(di);
676}
677
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200678function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100679 g_pars.p_tmsi := p_tmsi;
680 /* update TLLI */
681 g_pars.tlli_old := g_pars.tlli;
682 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100683 if (is_gb(ran_index)) {
684 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
685 }
Harald Weltef70997d2018-02-17 10:11:19 +0100686}
687
Harald Welte04683d02018-02-16 22:43:45 +0100688function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
689 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100690 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200691 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100692 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200693 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200694 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100695 }
Harald Welte04683d02018-02-16 22:43:45 +0100696 g_pars.ra := aa.routingAreaIdentification;
697 if (ispresent(aa.allocatedPTMSI)) {
698 if (not g_pars.net.expect_ptmsi) {
699 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200700 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100701 }
Harald Weltef70997d2018-02-17 10:11:19 +0100702 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100703 }
704 if (ispresent(aa.msIdentity)) {
705 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200706 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100707 }
708 /* P-TMSI.sig */
709 if (ispresent(aa.ptmsiSignature)) {
710 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
711 }
712 /* updateTimer */
713 // aa.readyTimer
714 /* T3302, T3319, T3323, T3312_ext, T3324 */
715}
716
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200717function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100718 /* mandatory IE */
719 g_pars.ra := ra.routingAreaId;
720 if (ispresent(ra.allocatedPTMSI)) {
721 if (not g_pars.net.expect_ptmsi) {
722 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200723 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100724 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200725 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100726 }
727 if (ispresent(ra.msIdentity)) {
728 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200729 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100730 }
731 /* P-TMSI.sig */
732 if (ispresent(ra.ptmsiSignature)) {
733 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
734 }
735 /* updateTimer */
736 // aa.readyTimer
737 /* T3302, T3319, T3323, T3312_ext, T3324 */
738}
739
740
Harald Welte5a4fa042018-02-16 20:59:21 +0100741function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
742 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
743}
744
Harald Welte23178c52018-02-17 09:36:33 +0100745/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700746private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100747 if (ispresent(g_pars.p_tmsi)) {
748 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
749 } else {
750 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
751 }
752}
753
Harald Welte311ec272018-02-17 09:40:03 +0100754private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100755 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100756 /* Expect MSC to perform LU with HLR */
757 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100758 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
759 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
760 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100761 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
762 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
763}
764
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200765friend 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 +0100766 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200767 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 +0200768 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100769
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200770 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
771 * 3G auth vectors */
772 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
773 /* The thing is, if the solSACapability is 'omit', then the
774 * revisionLevelIndicatior is at the wrong place! */
775 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
776
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200777 f_send_l3(attach_req, ran_index);
778 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200779 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100780 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100781
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200782 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200783 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
784
Harald Welte04683d02018-02-16 22:43:45 +0100785 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200786 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200787
788 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200789 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200790 as_iu_release_compl_disc();
791 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200792
793 /* Race condition
794 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
795 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
796 * arrived before it. This results in a test case failure.
797 * Delay execution by 50 ms
798 */
799 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200800}
801
802private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
803 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100804 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100805}
806
807testcase TC_attach() runs on test_CT {
808 var BSSGP_ConnHdlr vc_conn;
809 f_init();
810 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200811 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100812 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200813 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100814}
815
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100816testcase TC_attach_mnc3() runs on test_CT {
817 var BSSGP_ConnHdlr vc_conn;
818 f_init('023042'H);
819 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200820 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100821 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200822 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100823}
824
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200825private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
826 f_gmm_attach(true, false);
827 setverdict(pass);
828}
829testcase TC_attach_umts_aka_umts_res() runs on test_CT {
830 var BSSGP_ConnHdlr vc_conn;
831 f_init();
832 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200833 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200834 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200835 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200836}
837
838private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
839 f_gmm_attach(true, true);
840 setverdict(pass);
841}
842testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
843 var BSSGP_ConnHdlr vc_conn;
844 f_init();
845 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200846 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200847 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200848 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200849}
850
Harald Welte5b7c8122018-02-16 21:48:17 +0100851/* MS never responds to ID REQ, expect ATTACH REJECT */
852private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100853 var RoutingAreaIdentificationV old_ra := f_random_RAI();
854
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200855 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100856 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200857 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100858 /* don't send ID Response */
859 repeat;
860 }
Harald Welte955aa942019-05-03 01:29:29 +0200861 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100862 setverdict(pass);
863 }
Harald Welte955aa942019-05-03 01:29:29 +0200864 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100865 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200866 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100867 }
868 }
869}
870testcase TC_attach_auth_id_timeout() runs on test_CT {
871 var BSSGP_ConnHdlr vc_conn;
872 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200873 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 +0100874 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200875 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100876}
877
878/* HLR never responds to SAI REQ, expect ATTACH REJECT */
879private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100880 var RoutingAreaIdentificationV old_ra := f_random_RAI();
881
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200882 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100883 alt {
884 [] as_mm_identity();
885 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
886 }
887 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200888 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100889 setverdict(pass);
890}
891testcase TC_attach_auth_sai_timeout() runs on test_CT {
892 var BSSGP_ConnHdlr vc_conn;
893 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200894 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100895 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200896 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100897}
898
Harald Weltefe253882018-02-17 09:25:00 +0100899/* HLR rejects SAI, expect ATTACH REJECT */
900private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100901 var RoutingAreaIdentificationV old_ra := f_random_RAI();
902
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200903 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100904 alt {
905 [] as_mm_identity();
906 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
907 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
908 }
909 }
Harald Welte955aa942019-05-03 01:29:29 +0200910 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100911 setverdict(pass);
912}
913testcase TC_attach_auth_sai_reject() runs on test_CT {
914 var BSSGP_ConnHdlr vc_conn;
915 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200916 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100917 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200918 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100919}
920
Harald Welte5b7c8122018-02-16 21:48:17 +0100921/* HLR never responds to UL REQ, expect ATTACH REJECT */
922private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200923 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100924 var RoutingAreaIdentificationV old_ra := f_random_RAI();
925
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200926 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100927 f_gmm_auth();
928 /* Expect MSC to perform LU with HLR */
929 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
930 /* Never follow-up with ISD_REQ or UL_RES */
931 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200932 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100933 setverdict(pass);
934 }
Harald Welte955aa942019-05-03 01:29:29 +0200935 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
936 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100937 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200938 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100939 }
940 }
941}
942testcase TC_attach_gsup_lu_timeout() runs on test_CT {
943 var BSSGP_ConnHdlr vc_conn;
944 f_init();
945 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200946 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100947 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200948 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100949}
950
Harald Welteb7c14e92018-02-17 09:29:16 +0100951/* HLR rejects UL REQ, expect ATTACH REJECT */
952private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200953 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100954 var RoutingAreaIdentificationV old_ra := f_random_RAI();
955
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200956 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100957 f_gmm_auth();
958 /* Expect MSC to perform LU with HLR */
959 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
960 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
961 }
962 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200963 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100964 setverdict(pass);
965 }
Harald Welte955aa942019-05-03 01:29:29 +0200966 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
967 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100968 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200969 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100970 }
971 }
972}
973testcase TC_attach_gsup_lu_reject() runs on test_CT {
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200977 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100978 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200979 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100980}
981
982
Harald Welte3823e2e2018-02-16 21:53:48 +0100983/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
984private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200985 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100986 var RoutingAreaIdentificationV old_ra := f_random_RAI();
987
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200988 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100989 f_gmm_auth();
990 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100991 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100992
Harald Welte955aa942019-05-03 01:29:29 +0200993 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
994 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100995 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200996 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100997 setverdict(pass);
998}
Harald Welte3823e2e2018-02-16 21:53:48 +0100999testcase TC_attach_combined() runs on test_CT {
1000 var BSSGP_ConnHdlr vc_conn;
1001 f_init();
1002 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001003 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001004 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001005 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001006}
1007
Harald Welte76dee092018-02-16 22:12:59 +01001008/* Attempt of GPRS ATTACH in 'accept all' mode */
1009private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001010 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001011 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1012
1013 g_pars.net.expect_auth := false;
1014
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001015 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001016 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001017 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1018 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001019 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001020 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001021 setverdict(pass);
1022}
1023testcase TC_attach_accept_all() runs on test_CT {
1024 var BSSGP_ConnHdlr vc_conn;
1025 f_init();
1026 f_sleep(1.0);
1027 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001028 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001029 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001030 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001031}
Harald Welte5b7c8122018-02-16 21:48:17 +01001032
Harald Welteb2124b22018-02-16 22:26:56 +01001033/* Attempt of GPRS ATTACH in 'accept all' mode */
1034private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001035 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1036
1037 /* Simulate a foreign IMSI */
1038 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001039 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001040
1041 g_pars.net.expect_auth := false;
1042
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001043 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001044 alt {
1045 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001046 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001047 setverdict(pass);
1048 }
Harald Welte955aa942019-05-03 01:29:29 +02001049 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001050 setverdict(pass);
1051 }
Harald Welte955aa942019-05-03 01:29:29 +02001052 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001053 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001054 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001055 }
Harald Welteb2124b22018-02-16 22:26:56 +01001056 }
1057}
1058testcase TC_attach_closed() runs on test_CT {
1059 var BSSGP_ConnHdlr vc_conn;
1060 f_init();
1061 f_sleep(1.0);
1062 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1063 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001064 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001065 vc_conn.done;
1066 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001067 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001068 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001069 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001070}
1071
Harald Welte04683d02018-02-16 22:43:45 +01001072/* Routing Area Update from Unknown TLLI -> REJECT */
1073private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001074 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1075
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001076 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 +01001077 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001078 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001079 setverdict(pass);
1080 }
1081 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001082 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001083 }
1084}
1085testcase TC_rau_unknown() runs on test_CT {
1086 var BSSGP_ConnHdlr vc_conn;
1087 f_init();
1088 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001089 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001090 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001091 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001092}
1093
Harald Welte91636de2018-02-17 10:16:14 +01001094private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001095 /* first perform regular attach */
1096 f_TC_attach(id);
1097
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001098 f_routing_area_update(g_pars.ra);
1099
Harald Welte91636de2018-02-17 10:16:14 +01001100}
1101testcase TC_attach_rau() runs on test_CT {
1102 var BSSGP_ConnHdlr vc_conn;
1103 f_init();
1104 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001105 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001106 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001107 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001108}
Harald Welte04683d02018-02-16 22:43:45 +01001109
Harald Welte6abb9fe2018-02-17 15:24:48 +01001110/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001111function 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 +02001112 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001113 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001114 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001115 if (expect_purge) {
1116 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1117 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1118 }
1119 T.start;
1120 alt {
1121 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1122 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001123 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001124 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001125 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001126 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001127 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001128 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001129 /* TODO: check if any PDP contexts are deactivated on network side? */
1130 }
1131 [power_off] T.timeout {
1132 setverdict(pass);
1133 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001134 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001135 g_pars.ra := omit;
1136 setverdict(pass);
1137 /* TODO: check if any PDP contexts are deactivated on network side? */
1138 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001139 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001140 if (power_off) {
1141 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1142 } else {
1143 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1144 }
1145 mtc.stop;
1146 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001147 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001148 }
1149}
1150
1151/* IMSI DETACH (non-power-off) for unknown TLLI */
1152private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1153 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1154}
1155testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1156 var BSSGP_ConnHdlr vc_conn;
1157 f_init();
1158 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001159 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001160 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001161 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001162}
1163
1164/* IMSI DETACH (power-off) for unknown TLLI */
1165private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1166 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1167}
1168testcase TC_detach_unknown_poweroff() runs on test_CT {
1169 var BSSGP_ConnHdlr vc_conn;
1170 f_init();
1171 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001172 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001173 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001174 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001175}
1176
1177/* IMSI DETACH (non-power-off) for known TLLI */
1178private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1179 /* first perform regular attach */
1180 f_TC_attach(id);
1181
1182 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1183}
1184testcase TC_detach_nopoweroff() runs on test_CT {
1185 var BSSGP_ConnHdlr vc_conn;
1186 f_init();
1187 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001188 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001189 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001190 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001191}
1192
1193/* IMSI DETACH (power-off) for known TLLI */
1194private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1195 /* first perform regular attach */
1196 f_TC_attach(id);
1197
1198 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1199}
1200testcase TC_detach_poweroff() runs on test_CT {
1201 var BSSGP_ConnHdlr vc_conn;
1202 f_init();
1203 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001204 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001205 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001206 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001207}
1208
Harald Welteeded9ad2018-02-17 20:57:34 +01001209type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001210 BIT3 tid, /* L3 Transaction ID */
1211 BIT4 nsapi, /* SNDCP NSAPI */
1212 BIT4 sapi, /* LLC SAPI */
1213 QoSV qos, /* QoS parameters */
1214 PDPAddressV addr, /* IP address */
1215 octetstring apn optional, /* APN name */
1216 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1217 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001218 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001219 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001220
Harald Welte822f9102018-02-18 20:39:06 +01001221 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1222 OCT4 ggsn_tei_u, /* GGSN TEI User */
1223 octetstring ggsn_ip_c, /* GGSN IP Control */
1224 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001225 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001226
Harald Welte822f9102018-02-18 20:39:06 +01001227 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1228 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1229 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1230 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001231};
1232
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001233
1234private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1235 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1236 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1237 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1238 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1239 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1240 f_gtp_register_teid(apars.ggsn_tei_c);
1241 f_gtp_register_teid(apars.ggsn_tei_u);
1242}
1243
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001244function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001245runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001246 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1247 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001248 var template Recovery_gtpc recovery := omit;
1249
1250 if (send_recovery) {
1251 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1252 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001253
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001254 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 +02001255 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001256 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1257 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1258 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1259 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1260 apars.sgsn_tei_c, apars.gtp_resp_cause,
1261 apars.ggsn_tei_c, apars.ggsn_tei_u,
1262 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001263 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1264 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001265 }
1266 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001267 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001268 setverdict(pass);
1269 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001270 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001271 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001272 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001273 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001274 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001275 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001276 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001277 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001278 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001279 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1280 mtc.stop;
1281 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001282 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001283 setverdict(pass);
1284 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001285 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001286 }
1287}
1288
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001289function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001290runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001291 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1292 var Gtp1cUnitdata g_ud;
1293
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001294 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001295 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1296 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001297 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001298 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1299 }
1300 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001301 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001302 setverdict(pass);
1303 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001304 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001305 }
1306}
1307
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001308function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001309runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001310 var Gtp1cUnitdata g_ud;
1311 var integer seq_nr := 23;
1312 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1313
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001314 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001315 if (error_ind) {
1316 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1317 } else {
1318 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1319 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001320
1321 timer T := 5.0;
1322 T.start;
1323
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001324 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001325 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1326 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001327 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001328 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1329 repeat;
1330 }
1331 [] T.timeout {
1332 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1333 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001334 }
1335}
1336
Harald Welte6f203162018-02-18 22:04:55 +01001337
Harald Welteeded9ad2018-02-17 20:57:34 +01001338/* Table 10.5.156/3GPP TS 24.008 */
1339template (value) QoSV t_QosDefault := {
1340 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1341 delayClass := '100'B, /* best effort */
1342 spare1 := '00'B,
1343 precedenceClass := '010'B, /* normal */
1344 spare2 := '0'B,
1345 peakThroughput := '0000'B, /* subscribed */
1346 meanThroughput := '00000'B, /* subscribed */
1347 spare3 := '000'B,
1348 deliverErroneusSDU := omit,
1349 deliveryOrder := omit,
1350 trafficClass := omit,
1351 maxSDUSize := omit,
1352 maxBitrateUplink := omit,
1353 maxBitrateDownlink := omit,
1354 sduErrorRatio := omit,
1355 residualBER := omit,
1356 trafficHandlingPriority := omit,
1357 transferDelay := omit,
1358 guaranteedBitRateUplink := omit,
1359 guaranteedBitRateDownlink := omit,
1360 sourceStatisticsDescriptor := omit,
1361 signallingIndication := omit,
1362 spare4 := omit,
1363 maxBitrateDownlinkExt := omit,
1364 guaranteedBitRateDownlinkExt := omit,
1365 maxBitrateUplinkExt := omit,
1366 guaranteedBitRateUplinkExt := omit,
1367 maxBitrateDownlinkExt2 := omit,
1368 guaranteedBitRateDownlinkExt2 := omit,
1369 maxBitrateUplinkExt2 := omit,
1370 guaranteedBitRateUplinkExt2 := omit
1371}
1372
1373/* 10.5.6.4 / 3GPP TS 24.008 */
1374template (value) PDPAddressV t_AddrIPv4dyn := {
1375 pdpTypeOrg := '0001'B, /* IETF */
1376 spare := '0000'B,
1377 pdpTypeNum := '21'O, /* IPv4 */
1378 addressInfo := omit
1379}
1380template (value) PDPAddressV t_AddrIPv6dyn := {
1381 pdpTypeOrg := '0001'B, /* IETF */
1382 spare := '0000'B,
1383 pdpTypeNum := '53'O, /* IPv6 */
1384 addressInfo := omit
1385}
1386
Harald Welte37692d82018-02-18 15:21:34 +01001387template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001388 tid := '000'B,
1389 nsapi := '0101'B, /* < 5 are reserved */
1390 sapi := '0011'B, /* 3/5/9/11 */
1391 qos := t_QosDefault,
1392 addr := t_AddrIPv4dyn,
1393 apn := omit,
1394 pco := omit,
1395 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001396 gtp_resp_cause := int2oct(128, 1),
1397 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001398
1399 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001400 ggsn_tei_c := f_rnd_octstring(4),
1401 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001402 ggsn_ip_c := f_inet_addr(ggsn_ip),
1403 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001404 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001405
Harald Welteeded9ad2018-02-17 20:57:34 +01001406 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001407 sgsn_tei_u := omit,
1408 sgsn_ip_c := omit,
1409 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001410}
1411
Harald Welte37692d82018-02-18 15:21:34 +01001412template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1413 connId := 1,
1414 remName := f_inet_ntoa(ip),
1415 remPort := GTP1U_PORT
1416}
1417
1418template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1419 connId := 1,
1420 remName := f_inet_ntoa(ip),
1421 remPort := GTP1C_PORT
1422}
1423
1424private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1425 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1426 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1427}
1428
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001429private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1430 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001431 repeat;
1432 }
1433}
1434
1435template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1436 pDU_SN_UNITDATA := {
1437 nsapi := nsapi,
1438 moreBit := ?,
1439 snPduType := '1'B,
1440 firstSegmentIndicator := ?,
1441 spareBit := ?,
1442 pcomp := ?,
1443 dcomp := ?,
1444 npduNumber := ?,
1445 segmentNumber := ?,
1446 npduNumberContinued := ?,
1447 dataSegmentSnUnitdataPdu := payload
1448 }
1449}
1450
1451/* simple case: single segment, no compression */
1452template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1453 pDU_SN_UNITDATA := {
1454 nsapi := nsapi,
1455 moreBit := '0'B,
1456 snPduType := '1'B,
1457 firstSegmentIndicator := '1'B,
1458 spareBit := '0'B,
1459 pcomp := '0000'B,
1460 dcomp := '0000'B,
1461 npduNumber := '0000'B,
1462 segmentNumber := '0000'B,
1463 npduNumberContinued := '00'O,
1464 dataSegmentSnUnitdataPdu := payload
1465 }
1466}
1467
1468/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001469private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001470runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001471 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1472 f_gtpu_send(apars, payload);
1473 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1474 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001475 [] as_xid(apars, ran_index);
1476 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1477 [] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001478 }
1479}
1480
Harald Welte64d6b512020-06-17 16:42:00 +02001481/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001482private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001483runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001484 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1485 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1486 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001487 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001488 /* Expect PDU via GTP from SGSN on simulated GGSN */
1489 alt {
1490 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1491 }
1492}
1493
Harald Welteeded9ad2018-02-17 20:57:34 +01001494private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001495 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001496
1497 /* first perform regular attach */
1498 f_TC_attach(id);
1499
1500 f_pdp_ctx_act(apars);
1501}
1502testcase TC_attach_pdp_act() runs on test_CT {
1503 var BSSGP_ConnHdlr vc_conn;
1504 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001505 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001506 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001507 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001508}
Harald Welteb2124b22018-02-16 22:26:56 +01001509
Harald Welte835b15f2018-02-18 14:39:11 +01001510/* PDP Context activation for not-attached subscriber; expect fail */
1511private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001512 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001513 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 +01001514 apars.apn, apars.pco));
1515 alt {
1516 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001517 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001518 setverdict(pass);
1519 }
1520 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1521 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001522 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001523 }
Harald Welte955aa942019-05-03 01:29:29 +02001524 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001525 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001526 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001527 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001528 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001529 }
1530}
1531testcase TC_pdp_act_unattached() runs on test_CT {
1532 var BSSGP_ConnHdlr vc_conn;
1533 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001534 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001535 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001536 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001537}
1538
Harald Welte37692d82018-02-18 15:21:34 +01001539/* ATTACH + PDP CTX ACT + user plane traffic */
1540private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1541 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1542
1543 /* first perform regular attach */
1544 f_TC_attach(id);
1545 /* then activate PDP context */
1546 f_pdp_ctx_act(apars);
1547 /* then transceive a downlink PDU */
1548 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1549 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1550}
1551testcase TC_attach_pdp_act_user() runs on test_CT {
1552 var BSSGP_ConnHdlr vc_conn;
1553 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001554 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001555 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001556 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001557}
1558
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001559/* ATTACH + PDP CTX ACT; reject from GGSN */
1560private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1561 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1562
1563 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1564 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1565
1566 /* first perform regular attach */
1567 f_TC_attach(id);
1568 /* then activate PDP context */
1569 f_pdp_ctx_act(apars);
1570}
1571testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1572 var BSSGP_ConnHdlr vc_conn;
1573 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001574 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001575 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001576 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001577}
Harald Welte835b15f2018-02-18 14:39:11 +01001578
Harald Welte6f203162018-02-18 22:04:55 +01001579/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1580private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1581 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1582
1583 /* first perform regular attach */
1584 f_TC_attach(id);
1585 /* then activate PDP context */
1586 f_pdp_ctx_act(apars);
1587 /* then transceive a downlink PDU */
1588 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1589 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1590
1591 f_pdp_ctx_deact_mo(apars, '00'O);
1592}
1593testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1594 var BSSGP_ConnHdlr vc_conn;
1595 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001596 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 +01001597 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001598 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001599}
1600
Harald Welte57b9b7f2018-02-18 22:28:13 +01001601/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1602private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1603 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1604
1605 /* first perform regular attach */
1606 f_TC_attach(id);
1607 /* then activate PDP context */
1608 f_pdp_ctx_act(apars);
1609 /* then transceive a downlink PDU */
1610 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1611 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1612
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001613 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001614}
1615testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1616 var BSSGP_ConnHdlr vc_conn;
1617 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001618 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 +01001619 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001620 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001621}
1622
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001623/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1624private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1625 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1626 var Gtp1cUnitdata g_ud;
1627 var integer i;
1628 var OCT1 cause_regular_deact := '24'O;
1629
1630 /* first perform regular attach + PDP context act */
1631 f_TC_attach(id);
1632 f_pdp_ctx_act(apars);
1633
1634 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1635 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1636
1637 for (i := 0; i < 2; i := i+1) {
1638 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1639 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1640 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1641 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1642 }
1643 }
1644
1645 alt {
1646 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1647 setverdict(pass);
1648 }
1649 [] as_xid(apars, 0);
1650 }
1651
1652 /* Make sure second DeactPdpAccept is sent: */
1653 timer T := 2.0;
1654 T.start;
1655 alt {
1656 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1657 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1658 }
1659 [] T.timeout {
1660 setverdict(pass);
1661 }
1662 }
1663
1664 setverdict(pass);
1665}
1666testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1667 var BSSGP_ConnHdlr vc_conn;
1668 f_init();
1669 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1670 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001671 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001672}
1673
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001674/* ATTACH + ATTACH (2nd) */
1675private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1676 g_pars.t_guard := 5.0;
1677
1678 /* first perform regular attach */
1679 f_TC_attach(id);
1680
1681 /* second to perform regular attach */
1682 f_TC_attach(id);
1683}
1684
1685
1686testcase TC_attach_second_attempt() runs on test_CT {
1687 var BSSGP_ConnHdlr vc_conn;
1688 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001689 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001690 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001691 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001692}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001693
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001694private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1695 var Gtp1cUnitdata g_ud;
1696 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1697 var integer seq_nr;
1698
1699 /* first perform regular attach */
1700 f_TC_attach(id);
1701 /* then activate PDP context */
1702 f_pdp_ctx_act(apars);
1703
1704 /* Wait to receive first echo request and send initial Restart counter */
1705 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1706 BSSGP[0].clear;
1707 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1708 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1709 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1710 }
1711
1712 /* At some point next echo request not answered will timeout and SGSN
1713 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1714 timer T := 3.0 * 6.0 + 16.0;
1715 T.start;
1716 alt {
1717 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1718 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1719 setverdict(pass);
1720 }
1721 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1722 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1723 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1724 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1725 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1726 repeat;
1727 }
1728 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1729 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1730 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1731 repeat;
1732 }
1733 [] T.timeout {
1734 setverdict(fail, "BSSGP DeactPdpReq not received");
1735 mtc.stop;
1736 }
1737 [] as_xid(apars);
1738 }
1739 T.stop
1740
1741 setverdict(pass);
1742}
1743/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1744testcase TC_attach_echo_timeout() runs on test_CT {
1745 var BSSGP_ConnHdlr vc_conn;
1746 g_use_echo := true;
1747 f_init();
1748 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1749 vc_conn.done;
1750 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001751 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001752}
1753
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001754private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001755 var Gtp1cUnitdata g_ud;
1756 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1757
1758 /* first perform regular attach */
1759 f_TC_attach(id);
1760 /* Activate a pdp context against the GGSN */
1761 f_pdp_ctx_act(apars);
1762 /* Wait to receive first echo request and send initial Restart counter */
1763 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1764 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1765 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1766 }
1767 /* Wait to receive second echo request and send incremented Restart
1768 counter. This will fake a restarted GGSN, and pdp ctx allocated
1769 should be released by SGSN */
1770 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1771 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1772 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1773 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1774 }
1775 var OCT1 cause_network_failure := int2oct(38, 1)
1776 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001777 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001778 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001779 setverdict(pass);
1780 }
1781 [] as_xid(apars);
1782 }
1783 setverdict(pass);
1784}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001785/* ATTACH + trigger Recovery procedure through EchoResp */
1786testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001787 var BSSGP_ConnHdlr vc_conn;
1788 g_use_echo := true
1789 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001790 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 +02001791 vc_conn.done;
1792 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001793 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001794}
1795
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001796private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1797 var Gtp1cUnitdata g_ud;
1798 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1799 var integer seq_nr := 23;
1800 var GtpPeer peer;
1801 /* first perform regular attach */
1802 f_TC_attach(id);
1803
1804 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1805 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1806 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1807 f_pdp_ctx_act(apars, true);
1808
1809 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1810/* received. */
1811 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1812
1813 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1814 would be great to have an active pdp context here before triggering
1815 Recovery, and making sure the the DEACT request is sent by the SGSN.
1816 */
1817
1818 /* Activate a pdp context against the GGSN, send incremented Recovery
1819 IE. This should trigger the recovery path, but still this specific
1820 CTX activation should work. */
1821 apars.exp_rej_cause := omit; /* default value for tests */
1822 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1823 f_pdp_ctx_act(apars, true);
1824
1825 setverdict(pass);
1826}
1827/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1828testcase TC_attach_restart_ctr_create() runs on test_CT {
1829 var BSSGP_ConnHdlr vc_conn;
1830 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001831 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 +02001832 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001833 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001834}
1835
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001836/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1837private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1838 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1839 var integer seq_nr := 23;
1840 var GtpPeer peer;
1841 var integer i;
1842
1843 /* first perform regular attach */
1844 f_TC_attach(id);
1845 /* then activate PDP context */
1846 f_pdp_ctx_act(apars);
1847
Alexander Couzens0e510e62018-07-28 23:06:00 +02001848 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001849 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1850 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1851
1852 for (i := 0; i < 5; i := i+1) {
1853 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001854 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001855 [] as_xid(apars);
1856 }
1857 }
1858
1859 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1860
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001861 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001862 setverdict(pass);
1863}
1864testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1865 var BSSGP_ConnHdlr vc_conn;
1866 f_init();
1867 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001868 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 +02001869 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001870 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001871}
1872
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001873/* ATTACH + PDP CTX ACT dropped + retrans */
1874private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1875 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1876 var Gtp1cUnitdata g_ud_first, g_ud_second;
1877 /* first perform regular attach */
1878 f_TC_attach(id);
1879
1880 /* then activate PDP context on the Gb side */
1881 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1882 apars.apn, apars.pco), 0);
1883
1884 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1885 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1886 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1887 if (g_ud_first != g_ud_second) {
1888 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1889 mtc.stop;
1890 }
1891 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1892 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1893 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1894 apars.sgsn_tei_c, apars.gtp_resp_cause,
1895 apars.ggsn_tei_c, apars.ggsn_tei_u,
1896 apars.nsapi,
1897 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1898 omit, omit));
1899 }
Harald Welte955aa942019-05-03 01:29:29 +02001900 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001901
1902 /* Now the same with Deact */
1903 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1904 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1905 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1906 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1907 if (g_ud_first != g_ud_second) {
1908 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1909 mtc.stop;
1910 }
1911 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1912 BSSGP[0].clear;
1913 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1914 }
1915 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001916 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001917 setverdict(pass);
1918 }
1919 [] as_xid(apars, 0);
1920 }
1921
1922 setverdict(pass);
1923}
1924testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1925 var BSSGP_ConnHdlr vc_conn;
1926 f_init();
1927 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1928 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001929 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001930}
1931
1932/* Test that SGSN GTP response retransmit queue works fine */
1933private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1934 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1935 var integer seq_nr := 23;
1936 var Gtp1cUnitdata g_ud_first, g_ud_second;
1937 var template Gtp1cUnitdata g_delete_req;
1938 /* first perform regular attach + PDP context act */
1939 f_TC_attach(id);
1940 f_pdp_ctx_act(apars);
1941
1942 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1943 BSSGP[0].clear;
1944 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1945 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1946 GTP.send(g_delete_req);
1947 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001948 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001949 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1950 }
1951 [] as_xid(apars, 0);
1952 }
1953 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1954 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1955 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1956 mtc.stop;
1957 }
1958 };
1959
1960 /* Send duplicate DeleteCtxReq */
1961 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1962 GTP.send(g_delete_req);
1963 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1964 if (g_ud_first != g_ud_second) {
1965 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1966 mtc.stop;
1967 }
1968 }
1969
1970 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1971 * is handled differently by SGSN (expect "non-existent" cause) */
1972 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1973 GTP.send(g_delete_req);
1974 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1975 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1976 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1977 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1978 mtc.stop;
1979 }
1980 }
1981
1982 setverdict(pass);
1983}
1984testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1985 var BSSGP_ConnHdlr vc_conn;
1986 f_init();
1987 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1988 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001989 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001990}
1991
Alexander Couzens5e307b42018-05-22 18:12:20 +02001992private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1993 /* MS: perform regular attach */
1994 f_TC_attach(id);
1995
1996 /* HLR: cancel the location request */
1997 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1998 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001999
2000 /* ensure no Detach Request got received */
2001 timer T := 5.0;
2002 T.start;
2003 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002004 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002005 T.stop;
2006 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002007 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002008 }
2009 [] T.timeout {
2010 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002011 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002012 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002013 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002014 repeat;
2015 }
2016 }
2017}
2018
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002019/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2020private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2021 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2022
2023 /* first perform regular attach */
2024 f_TC_attach(id);
2025 /* then activate PDP context */
2026 f_pdp_ctx_act(apars);
2027 /* then transceive a downlink PDU */
2028 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2029
2030 /* Send Error indication as response from upload PDU and expect deact towards MS */
2031 f_pdp_ctx_deact_mt(apars, true);
2032}
2033testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2034 var BSSGP_ConnHdlr vc_conn;
2035 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002036 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 +02002037 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002038 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002039}
2040
Alexander Couzens5e307b42018-05-22 18:12:20 +02002041testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2042 /* MS <-> SGSN: GMM Attach
2043 * HLR -> SGSN: Cancel Location Request
2044 * HLR <- SGSN: Cancel Location Ack
2045 */
2046 var BSSGP_ConnHdlr vc_conn;
2047 f_init();
2048 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002049 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002050 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002051 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002052}
2053
2054
Alexander Couzensc87967a2018-05-22 16:09:54 +02002055private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2056 /* MS: perform regular attach */
2057 f_TC_attach(id);
2058
2059 /* HLR: cancel the location request */
2060 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2061 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2062 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2063
2064 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002065 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002066 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002067
2068 setverdict(pass);
2069}
2070
2071testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2072 /* MS <-> SGSN: GMM Attach
2073 * HLR -> SGSN: Cancel Location Request
2074 * HLR <- SGSN: Cancel Location Ack
2075 * MS <- SGSN: Detach Request
2076 * SGSN-> MS: Detach Complete
2077 */
2078 var BSSGP_ConnHdlr vc_conn;
2079 f_init();
2080 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002081 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002082 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002083 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002084}
2085
2086
Alexander Couzens6c47f292018-05-22 17:09:49 +02002087private function f_hlr_location_cancel_request_unknown_subscriber(
2088 charstring id,
2089 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2090
2091 /* HLR: cancel the location request */
2092 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2093
2094 /* cause 2 = IMSI_UNKNOWN */
2095 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2096
2097 setverdict(pass);
2098}
2099
2100private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002101 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002102}
2103
2104testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2105 /* HLR -> SGSN: Cancel Location Request
2106 * HLR <- SGSN: Cancel Location Error
2107 */
2108
2109 var BSSGP_ConnHdlr vc_conn;
2110 f_init();
2111 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002112 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 +02002113 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002114 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002115}
2116
2117private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002118 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002119}
2120
2121testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2122 /* HLR -> SGSN: Cancel Location Request
2123 * HLR <- SGSN: Cancel Location Error
2124 */
2125
2126 var BSSGP_ConnHdlr vc_conn;
2127 f_init();
2128 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002129 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 +02002130 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002131 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002132}
2133
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002134private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2135 f_TC_attach(id);
2136 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2137}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002138
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002139testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2140 /* MS <-> SGSN: Attach
2141 * MS -> SGSN: Detach Req (Power off)
2142 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2143 */
2144 var BSSGP_ConnHdlr vc_conn;
2145 var integer id := 33;
2146 var charstring imsi := hex2str(f_gen_imsi(id));
2147
2148 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002149 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002150 vc_conn.done;
2151
2152 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002153 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002154}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002155
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002156/* Attempt an attach, but loose the Identification Request (IMEI) */
2157private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2158 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002159 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002160
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002161 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 +02002162
2163 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002164 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002165 /* break */
2166 }
Harald Welte955aa942019-05-03 01:29:29 +02002167 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002168 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002169 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002170 repeat;
2171 }
Harald Welte955aa942019-05-03 01:29:29 +02002172 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002173 /* ignore ID REQ IMEI */
2174 count_req := count_req + 1;
2175 repeat;
2176 }
2177 }
2178 if (count_req != 5) {
2179 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002180 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002181 }
2182 setverdict(pass);
2183}
2184
2185testcase TC_attach_no_imei_response() runs on test_CT {
2186 /* MS -> SGSN: Attach Request IMSI
2187 * MS <- SGSN: Identity Request IMSI (optional)
2188 * MS -> SGSN: Identity Response IMSI (optional)
2189 * MS <- SGSN: Identity Request IMEI
2190 * MS -x SGSN: no response
2191 * MS <- SGSN: re-send: Identity Request IMEI 4x
2192 * MS <- SGSN: Attach Reject
2193 */
2194 var BSSGP_ConnHdlr vc_conn;
2195 f_init();
2196 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002197 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 +02002198 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002199 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002200}
2201
Alexander Couzens53f20562018-06-12 16:24:12 +02002202/* Attempt an attach, but loose the Identification Request (IMSI) */
2203private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2204 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002205 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002206
2207 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2208 g_pars.p_tmsi := 'c0000035'O;
2209
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002210 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 +02002211
2212 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002213 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002214 /* break */
2215 }
Harald Welte955aa942019-05-03 01:29:29 +02002216 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002217 /* ignore ID REQ IMSI */
2218 count_req := count_req + 1;
2219 repeat;
2220 }
Harald Welte955aa942019-05-03 01:29:29 +02002221 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002222 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002223 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002224 repeat;
2225 }
2226 }
2227 if (count_req != 5) {
2228 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002229 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002230 }
2231 setverdict(pass);
2232}
2233
2234testcase TC_attach_no_imsi_response() runs on test_CT {
2235 /* MS -> SGSN: Attach Request TMSI (unknown)
2236 * MS <- SGSN: Identity Request IMEI (optional)
2237 * MS -> SGSN: Identity Response IMEI (optional)
2238 * MS <- SGSN: Identity Request IMSI
2239 * MS -x SGSN: no response
2240 * MS <- SGSN: re-send: Identity Request IMSI 4x
2241 * MS <- SGSN: Attach Reject
2242 */
2243 var BSSGP_ConnHdlr vc_conn;
2244 f_init();
2245 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002246 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 +02002247 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002248 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002249}
2250
Alexander Couzenscf818962018-06-05 18:00:00 +02002251private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2252 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2253}
2254
2255testcase TC_attach_check_subscriber_list() runs on test_CT {
2256 /* MS <-> SGSN: Attach
2257 * VTY -> SGSN: Check if MS is in subscriber cache
2258 */
2259 var BSSGP_ConnHdlr vc_conn;
2260 var integer id := 34;
2261 var charstring imsi := hex2str(f_gen_imsi(id));
2262
2263 f_init();
2264 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002265 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002266 vc_conn.done;
2267
2268 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2269 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002270 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002271}
2272
Alexander Couzensf9858652018-06-07 16:14:53 +02002273private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2274 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002275 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002276
2277 /* unregister the old IMSI */
2278 f_bssgp_client_unregister(g_pars.imsi);
2279 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002280 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002281 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002282
2283 /* there is no auth */
2284 g_pars.net.expect_auth := false;
2285
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002286 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002287 f_gmm_auth();
2288 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002289 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002290 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002291 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002292 }
Harald Welte955aa942019-05-03 01:29:29 +02002293 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2294 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002295 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002296 setverdict(pass);
2297 }
2298 }
2299}
Alexander Couzens03d12242018-08-07 16:13:52 +02002300
2301private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2302
2303 f_TC_attach_closed_foreign(id);
2304 f_TC_attach_closed_imsi_added(id);
2305
2306}
2307
2308
Alexander Couzensf9858652018-06-07 16:14:53 +02002309testcase TC_attach_closed_add_vty() runs on test_CT {
2310 /* VTY-> SGSN: policy close
2311 * MS -> SGSN: Attach Request
2312 * MS <- SGSN: Identity Request IMSI
2313 * MS -> SGSN: Identity Response IMSI
2314 * MS <- SGSN: Attach Reject
2315 * VTY-> SGSN: policy imsi-acl add IMSI
2316 * MS -> SGSN: Attach Request
2317 * MS <- SGSN: Identity Request IMSI
2318 * MS -> SGSN: Identity Response IMSI
2319 * MS <- SGSN: Identity Request IMEI
2320 * MS -> SGSN: Identity Response IMEI
2321 * MS <- SGSN: Attach Accept
2322 */
2323 var BSSGP_ConnHdlr vc_conn;
2324 f_init();
2325 f_sleep(1.0);
2326 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2327 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002328 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2329 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002330 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002331 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002332 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002333 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002334}
2335
Alexander Couzens0085bd72018-06-12 19:08:44 +02002336/* Attempt an attach, but never answer a Attach Complete */
2337private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2338 var integer count_req := 0;
2339
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002340 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 +02002341 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002342 /* Expect SGSN to perform LU with HLR */
2343 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002344
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002345 timer T := 10.0;
2346 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002347 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002348 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002349 /* break */
2350 }
Harald Welte955aa942019-05-03 01:29:29 +02002351 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002352 /* ignore */
2353 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002354 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002355 repeat;
2356 }
2357 }
2358 if (count_req != 5) {
2359 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002360 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002361 }
2362 setverdict(pass);
2363}
2364
2365testcase TC_attach_check_complete_resend() runs on test_CT {
2366 /* MS -> SGSN: Attach Request IMSI
2367 * MS <- SGSN: Identity Request *
2368 * MS -> SGSN: Identity Response *
2369 * MS <- SGSN: Attach Complete 5x
2370 */
2371 var BSSGP_ConnHdlr vc_conn;
2372 f_init();
2373 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002374 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 +02002375 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002376 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002377}
2378
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002379friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002380 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002381 var PDU_DTAP_PS_MT mt;
2382 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002383
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002384 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002385 p_tmsi := g_pars.p_tmsi;
2386 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002387 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002388 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 +02002389 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002390 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2391 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2392 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002393 setverdict(pass);
2394 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002395 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2396 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2397 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002398 setverdict(pass);
2399 }
2400
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002401 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002402 setverdict(fail, "Unexpected RAU Reject");
2403 mtc.stop;
2404 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002405 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002406 setverdict(fail, "Unexpected RAU Reject");
2407 mtc.stop;
2408 }
2409
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002410 [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 +02002411 key_sts := ?)) {
2412 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2413 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002414 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002415 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002416 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002417 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2418 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002419 }
2420}
2421
Alexander Couzensbfda9212018-07-31 03:17:33 +02002422private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002423 /* first perform regular attach */
2424 f_TC_attach(id);
2425
2426 /* then send RAU */
2427 f_routing_area_update(g_pars.ra);
2428
2429 /* do another RAU */
2430 f_routing_area_update(g_pars.ra);
2431
2432 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2433}
2434
2435testcase TC_attach_rau_a_a() runs on test_CT {
2436 /* MS <-> SGSN: Successful Attach
2437 * MS -> SGSN: Routing Area Update Request
2438 * MS <- SGSN: Routing Area Update Accept
2439 * MS -> SGSN: Routing Area Update Request
2440 * MS <- SGSN: Routing Area Update Accept
2441 * MS -> SGSN: Detach (PowerOff)
2442 */
2443 var BSSGP_ConnHdlr vc_conn;
2444 f_init();
2445 f_sleep(1.0);
2446 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2447 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002448 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002449}
2450
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002451private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002452 f_TC_attach(id);
2453
2454 log("attach complete sending rau");
2455 f_routing_area_update(g_pars.ra, 0);
2456
2457 log("rau complete unregistering");
2458 f_bssgp_client_unregister(g_pars.imsi);
2459 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2460
2461 log("sending second RAU via different RA");
2462 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2463
2464 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2465}
2466
2467testcase TC_attach_rau_a_b() runs on test_CT {
2468 /* MS <-> SGSN: Successful Attach
2469 * MS -> SGSN: Routing Area _a_ Update Request
2470 * MS <- SGSN: Routing Area _a_ Update Accept
2471 * MS -> SGSN: Routing Area _b_ Update Request
2472 * MS <- SGSN: Routing Area _b_ Update Accept
2473 * MS -> SGSN: Detach (PowerOff)
2474 */
2475 var BSSGP_ConnHdlr vc_conn;
2476 f_init();
2477 f_sleep(1.0);
2478 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2479 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002480 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002481}
2482
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002483private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2484 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002485 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002486 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002487 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002488
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002489 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002490
2491 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002492 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002493 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2494 mtc.stop;
2495 }
Harald Welte955aa942019-05-03 01:29:29 +02002496 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002497 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002498 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002499 repeat;
2500 }
Harald Welte955aa942019-05-03 01:29:29 +02002501 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002502 /* send out a second GMM_Attach Request.
2503 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2504 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002505 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002506 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002507 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002508 }
2509 }
2510 f_sleep(1.0);
2511
2512 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2513 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002514 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002515 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002516 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002517 repeat;
2518 }
Harald Welte955aa942019-05-03 01:29:29 +02002519 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002520 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2521 mtc.stop;
2522 }
Harald Welte955aa942019-05-03 01:29:29 +02002523 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002524 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2525 mtc.stop;
2526 }
Harald Welte955aa942019-05-03 01:29:29 +02002527 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2528 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002529 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002530 setverdict(pass);
2531 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2532 }
2533 }
2534}
2535
2536testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2537 /* Testing if the SGSN ignore Attach Request with the exact same content */
2538 /* MS -> SGSN: Attach Request IMSI
2539 * MS <- SGSN: Identity Request IMSI (optional)
2540 * MS -> SGSN: Identity Response IMSI (optional)
2541 * MS <- SGSN: Identity Request IMEI
2542 * MS -> SGSN: Attach Request (2nd)
2543 * MS <- SGSN: Identity Response IMEI
2544 * MS <- SGSN: Attach Accept
2545 * MS -> SGSN: Attach Complete
2546 */
2547 var BSSGP_ConnHdlr vc_conn;
2548 f_init();
2549 f_sleep(1.0);
2550 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2551 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2552 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002553 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002554}
2555
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002556private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002557 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2558
2559 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2560
2561 /* send Attach Request */
2562 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2563 * 3G auth vectors */
2564 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2565 /* The thing is, if the solSACapability is 'omit', then the
2566 * revisionLevelIndicatior is at the wrong place! */
2567 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002568 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002569
2570 /* do the auth */
2571 var PDU_L3_MS_SGSN l3_mo;
2572 var PDU_L3_SGSN_MS l3_mt;
2573 var default di := activate(as_mm_identity());
2574
2575 var GSUP_IE auth_tuple;
2576 var template AuthenticationParameterAUTNTLV autn;
2577
2578 g_pars.vec := f_gen_auth_vec_3g();
2579 autn := {
2580 elementIdentifier := '28'O,
2581 lengthIndicator := lengthof(g_pars.vec.autn),
2582 autnValue := g_pars.vec.autn
2583 };
2584 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2585 g_pars.vec.sres,
2586 g_pars.vec.kc,
2587 g_pars.vec.ik,
2588 g_pars.vec.ck,
2589 g_pars.vec.autn,
2590 g_pars.vec.res));
2591 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2592 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2593 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2594
2595 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2596 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002597 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002598
2599 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002600 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002601
2602 /* wait for the GSUP resync request */
2603 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2604 g_pars.imsi,
2605 g_pars.vec.auts,
2606 g_pars.vec.rand));
2607
2608 /* generate new key material */
2609 g_pars.vec := f_gen_auth_vec_3g();
2610 autn := {
2611 elementIdentifier := '28'O,
2612 lengthIndicator := lengthof(g_pars.vec.autn),
2613 autnValue := g_pars.vec.autn
2614 };
2615
2616 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2617 g_pars.vec.sres,
2618 g_pars.vec.kc,
2619 g_pars.vec.ik,
2620 g_pars.vec.ck,
2621 g_pars.vec.autn,
2622 g_pars.vec.res));
2623 /* send new key material */
2624 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2625
2626 /* wait for the new Auth Request */
2627 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2628 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002629 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002630 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2631 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2632 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2633 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2634 valueField := substr(g_pars.vec.res, 0, 4)
2635 };
2636 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2637 elementIdentifier := '21'O,
2638 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2639 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2640 };
2641 l3_mo := valueof(auth_ciph_resp);
2642 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2643 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2644 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2645 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2646 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002647 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002648 deactivate(di);
2649
2650 /* Expect SGSN to perform LU with HLR */
2651 f_gmm_gsup_lu_isd();
2652
Harald Welte955aa942019-05-03 01:29:29 +02002653 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2654 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002655 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002656 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002657 setverdict(pass);
2658}
2659
2660testcase TC_attach_usim_resync() runs on test_CT {
2661 /* MS -> SGSN: Attach Request
2662 * MS <- SGSN: Identity Request IMSI
2663 * MS -> SGSN: Identity Response IMSI
2664 * MS <- SGSN: Identity Request IMEI
2665 * MS -> SGSN: Identity Response IMEI
2666 * HLR<- SGSN: SAI Request
2667 * HLR-> SGSN: SAI Response
2668 * MS <- SGSN: Auth Request
2669 * MS -> SGSN: Auth Failure (with AUTS)
2670 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2671 * HLR-> SGSN: SAI Response (new key material)
2672 * MS <- SGSN: Auth Request (new key material)
2673 * MS -> SGSN: Auth Response
2674 * MS <- SGSN: Attach Accept
2675 * MS -> SGSN: Attach Complete
2676 */
2677 var BSSGP_ConnHdlr vc_conn;
2678 f_init();
2679 f_sleep(1.0);
2680 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2681 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002682 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002683}
2684
Harald Weltea05b8072019-04-23 22:35:05 +02002685
2686/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2687private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2688 f_gmm_attach(false, false);
2689 f_sleep(1.0);
2690 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2691 /* try to detach to check if SGSN is still alive */
2692 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2693}
2694testcase TC_llc_null() runs on test_CT {
2695 var BSSGP_ConnHdlr vc_conn;
2696 f_init();
2697 f_sleep(1.0);
2698 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2699 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002700 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002701}
2702
Harald Welte645a1512019-04-23 23:18:23 +02002703/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2704private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2705 f_gmm_attach(false, false);
2706 f_sleep(1.0);
2707 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002708 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002709 setverdict(pass);
2710}
2711testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2712 var BSSGP_ConnHdlr vc_conn;
2713 f_init();
2714 f_sleep(1.0);
2715 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2716 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002717 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002718}
2719
2720/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2721private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2722 f_gmm_attach(false, false);
2723 f_sleep(1.0);
2724 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002725 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002726 setverdict(pass);
2727}
2728testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2729 var BSSGP_ConnHdlr vc_conn;
2730 f_init();
2731 f_sleep(1.0);
2732 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2733 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002734 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002735}
2736
Harald Welte2aaac1b2019-05-02 10:02:53 +02002737/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2738private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2739 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2740 var template (value) XID_Information xid;
2741 var template XID_Information xid_rx;
2742
2743 /* first perform regular attach */
2744 f_TC_attach(id);
2745 /* then activate PDP context */
2746 f_pdp_ctx_act(apars);
2747
2748 /* start MO XID */
2749 xid := { ts_XID_L3(''O) };
2750 xid_rx := { tr_XID_L3(''O) };
2751 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2752 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002753 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002754 [] as_xid(apars);
2755 }
2756 setverdict(pass);
2757}
2758testcase TC_xid_empty_l3() runs on test_CT {
2759 var BSSGP_ConnHdlr vc_conn;
2760 f_init();
2761 f_sleep(1.0);
2762 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2763 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002764 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002765}
2766
2767private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2768 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2769 var template (value) XID_Information xid;
2770 var template XID_Information xid_rx;
2771
2772 /* first perform regular attach */
2773 f_TC_attach(id);
2774 /* then activate PDP context */
2775 f_pdp_ctx_act(apars);
2776
2777 /* start MO XID */
2778 xid := { ts_XID_N201U(1234) };
2779 xid_rx := { tr_XID_N201U(1234) };
2780 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2781 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002782 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002783 [] as_xid(apars);
2784 }
2785 setverdict(pass);
2786}
2787testcase TC_xid_n201u() runs on test_CT {
2788 var BSSGP_ConnHdlr vc_conn;
2789 f_init();
2790 f_sleep(1.0);
2791 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2792 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002793 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002794}
2795
Alexander Couzens6bee0872019-05-11 01:48:50 +02002796private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2797 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2798
2799 /* first perform regular attach */
2800 f_TC_attach(id);
2801 /* then activate PDP context */
2802 f_pdp_ctx_act(apars);
2803 /* do a normal detach */
2804 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2805}
2806
2807testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2808 /* MS -> SGSN: Attach Request
2809 * MS <-> SGSN: [..]
2810 * MS -> SGSN: Attach Complete
2811 * MS -> SGSN: PDP Activate Request
2812 * MS <- SGSN: PDP Activate Accept
2813 * MS -> SGSN: GMM Detach Request
2814 * MS <- SGSN: GMM Detach Accept
2815 */
2816 var BSSGP_ConnHdlr vc_conn;
2817 f_init();
2818 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2819 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002820 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002821}
Harald Welte645a1512019-04-23 23:18:23 +02002822
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002823private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2824 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2825 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2826 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2827 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2828 var PDU_L3_SGSN_MS l3_mt;
2829
2830 f_send_l3(attach_req, 0);
2831
2832 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2833
2834 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2835 alt {
2836 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2837 setverdict(pass);
2838 }
2839 [] BSSGP[0].receive { repeat; }
2840 }
2841}
2842
2843/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2844 * See OS#3957 and OS#4245 for more information.
2845 */
2846testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2847 /*
2848 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2849 * MS <-- SGSN: Identity Request (IMEI)
2850 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2851 */
2852 var BSSGP_ConnHdlr vc_conn;
2853 f_init();
2854 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2855 vc_conn.done;
2856 f_cleanup();
2857}
2858
Harald Welte5ac31492018-02-15 20:39:13 +01002859control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002860 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002861 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002862 execute( TC_attach_umts_aka_umts_res() );
2863 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002864 execute( TC_attach_auth_id_timeout() );
2865 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002866 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002867 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002868 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002869 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002870 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002871 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002872 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002873 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002874 execute( TC_attach_closed_add_vty(), 20.0 );
2875 execute( TC_attach_check_subscriber_list(), 20.0 );
2876 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002877 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002878 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2879 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2880 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2881 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002882 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002883 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002884 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002885 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002886 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002887 execute( TC_detach_unknown_nopoweroff() );
2888 execute( TC_detach_unknown_poweroff() );
2889 execute( TC_detach_nopoweroff() );
2890 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002891 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002892 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002893 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002894 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002895 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002896 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002897 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002898 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002899 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002900 execute( TC_attach_restart_ctr_echo() );
2901 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002902 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002903 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2904 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002905 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002906 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002907 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002908
Harald Welte2aaac1b2019-05-02 10:02:53 +02002909 execute( TC_xid_empty_l3() );
2910 execute( TC_xid_n201u() );
2911
Harald Weltea05b8072019-04-23 22:35:05 +02002912 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002913 execute( TC_llc_sabm_dm_llgmm() );
2914 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002915
2916 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
2917 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01002918}
Harald Welte96a33b02018-02-04 10:36:22 +01002919
2920
2921
2922}