blob: 4a477239e3ce83e37bc9a0622fcee0e2dc273ba7 [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 Welte96a33b02018-02-04 10:36:22 +010014import from General_Types all;
15import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010016import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010017import from NS_Types all;
18import from NS_Emulation all;
19import from BSSGP_Types all;
20import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010021import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020022import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010023
24import from MobileL3_CommonIE_Types all;
25import from MobileL3_GMM_SM_Types all;
26import from MobileL3_Types all;
27import from L3_Templates all;
28import from L3_Common all;
29
30import from GSUP_Emulation all;
31import from GSUP_Types all;
32import from IPA_Emulation all;
33
Harald Welte26fbb6e2019-04-14 17:32:46 +020034import from RAN_Adapter all;
35import from RAN_Emulation all;
36import from RANAP_Templates all;
37import from RANAP_PDU_Descriptions all;
38import from RANAP_IEs all;
39
Harald Welteeded9ad2018-02-17 20:57:34 +010040import from GTP_Emulation all;
41import from GTP_Templates all;
42import from GTP_CodecPort all;
43import from GTPC_Types all;
44import from GTPU_Types all;
45
Harald Weltea2526a82018-02-18 19:03:36 +010046import from LLC_Types all;
47import from LLC_Templates all;
48
49import from SNDCP_Types all;
50
Harald Weltebd194722018-02-16 22:11:08 +010051import from TELNETasp_PortType all;
52import from Osmocom_VTY_Functions all;
53
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010054import from GSM_RR_Types all;
55
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020056import from MobileL3_MM_Types all;
57
Harald Welteeded9ad2018-02-17 20:57:34 +010058
Harald Welte5ac31492018-02-15 20:39:13 +010059modulepar {
60 /* IP/port on which we run our internal GSUP/HLR emulation */
61 charstring mp_hlr_ip := "127.0.0.1";
62 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010063 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020064 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020065
Alexander Couzensf3c1b412018-08-24 00:42:51 +020066 NSConfigurations mp_nsconfig := {
67 {
68 local_udp_port := 21010,
69 local_ip := "127.0.0.1",
70 remote_udp_port := 23000,
71 remote_ip := "127.0.0.1",
72 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020073 nsei := 96,
74 role_sgsn := false,
75 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020076 },
77 {
78 local_udp_port := 21011,
79 local_ip := "127.0.0.1",
80 remote_udp_port := 23000,
81 remote_ip := "127.0.0.1",
82 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020083 nsei := 97,
84 role_sgsn := false,
85 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020086 },
87 {
88 local_udp_port := 21012,
89 local_ip := "127.0.0.1",
90 remote_udp_port := 23000,
91 remote_ip := "127.0.0.1",
92 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020093 nsei := 98,
94 role_sgsn := false,
95 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020096 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020097 };
Harald Welte26fbb6e2019-04-14 17:32:46 +020098
99 RAN_Configurations mp_ranap_cfg := {
100 {
101 transport := RANAP_TRANSPORT_IuCS,
102 sccp_service_type := "mtp3_itu",
103 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
104 own_pc := 195,
105 own_ssn := 142,
106 peer_pc := 188, /* 0.23.4 */
107 peer_ssn := 142,
108 sio := '83'O,
109 rctx := 2
110 }
111 }
Harald Welte5ac31492018-02-15 20:39:13 +0100112};
113
114type record GbInstance {
115 NS_CT vc_NS,
116 BSSGP_CT vc_BSSGP,
117 BssgpConfig cfg
118};
Harald Welte96a33b02018-02-04 10:36:22 +0100119
Harald Welte2fa771f2019-05-02 20:13:53 +0200120const integer NUM_GB := 3;
121type record length(NUM_GB) of GbInstance GbInstances;
122type record length(NUM_GB) of NSConfiguration NSConfigurations;
123type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200124
Harald Welte26fbb6e2019-04-14 17:32:46 +0200125const integer NUM_RNC := 1;
126type record of RAN_Configuration RAN_Configurations;
127
Harald Welte96a33b02018-02-04 10:36:22 +0100128type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200129 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200130 var RAN_Adapter g_ranap[NUM_RNC];
Harald Welte96a33b02018-02-04 10:36:22 +0100131
Harald Welte5ac31492018-02-15 20:39:13 +0100132 var GSUP_Emulation_CT vc_GSUP;
133 var IPA_Emulation_CT vc_GSUP_IPA;
134 /* only to get events from IPA underneath GSUP */
135 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100136
Harald Welteeded9ad2018-02-17 20:57:34 +0100137 var GTP_Emulation_CT vc_GTP;
138
Harald Weltebd194722018-02-16 22:11:08 +0100139 port TELNETasp_PT SGSNVTY;
140
Harald Welte96a33b02018-02-04 10:36:22 +0100141 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200142 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100143};
144
Harald Welte26fbb6e2019-04-14 17:32:46 +0200145type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100146 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100147 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200148 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100149}
150
151type record SGSN_ConnHdlrNetworkPars {
152 boolean expect_ptmsi,
153 boolean expect_auth,
154 boolean expect_ciph
155};
156
157type record BSSGP_ConnHdlrPars {
158 /* IMEI of the simulated ME */
159 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200160 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100161 hexstring imsi,
162 /* MSISDN of the simulated MS (probably unused) */
163 hexstring msisdn,
164 /* P-TMSI allocated to the simulated MS */
165 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100166 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100167 /* TLLI of the simulated MS */
168 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100169 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100170 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200171 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200172 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
173 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100174 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100175 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200176 float t_guard,
177 /* only in IuPS / RANAP case */
178 SCCP_PAR_Address sccp_addr_local,
179 SCCP_PAR_Address sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100180};
181
Alexander Couzens89508702018-07-31 04:16:10 +0200182private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200183 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200184 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
185
186 var RoutingAreaIdentificationV ret := {
187 mccDigit1 := mcc_mnc[0],
188 mccDigit2 := mcc_mnc[1],
189 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200190 mncDigit3 := mcc_mnc[3],
191 mncDigit1 := mcc_mnc[4],
192 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200193 lac := int2oct(cell_id.ra_id.lai.lac, 16),
194 rac := int2oct(cell_id.ra_id.rac, 8)
195 }
196 return ret;
197};
198
Alexander Couzens51114d12018-07-31 18:41:56 +0200199private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
200 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
201 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100202 /* connect lower end of BSSGP emulation with NS upper port */
203 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
204 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
205 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
206
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200207 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100208 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
209}
210
211private function f_init_gsup(charstring id) runs on test_CT {
212 id := id & "-GSUP";
213 var GsupOps ops := {
214 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
215 };
216
217 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
218 vc_GSUP := GSUP_Emulation_CT.create(id);
219
220 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
221 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
222 /* we use this hack to get events like ASP_IPA_EVENT_UP */
223 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
224
225 vc_GSUP.start(GSUP_Emulation.main(ops, id));
226 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
227
228 /* wait for incoming connection to GSUP port before proceeding */
229 timer T := 10.0;
230 T.start;
231 alt {
232 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
233 [] T.timeout {
234 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200235 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100236 }
237 }
238}
239
Harald Welteeded9ad2018-02-17 20:57:34 +0100240private function f_init_gtp(charstring id) runs on test_CT {
241 id := id & "-GTP";
242
243 var GtpEmulationCfg gtp_cfg := {
244 gtpc_bind_ip := mp_ggsn_ip,
245 gtpc_bind_port := GTP1C_PORT,
246 gtpu_bind_ip := mp_ggsn_ip,
247 gtpu_bind_port := GTP1U_PORT,
248 sgsn_role := false
249 };
250
251 vc_GTP := GTP_Emulation_CT.create(id);
252 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
253}
254
Harald Weltebd194722018-02-16 22:11:08 +0100255private function f_init_vty() runs on test_CT {
256 map(self:SGSNVTY, system:SGSNVTY);
257 f_vty_set_prompts(SGSNVTY);
258 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200259 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100260 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
261}
262
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200263private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
264 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200265 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200266 } else {
267 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
268 }
269}
270
Harald Weltebd194722018-02-16 22:11:08 +0100271
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200272/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
273function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200274 var integer i;
275
Harald Welte96a33b02018-02-04 10:36:22 +0100276 if (g_initialized == true) {
277 return;
278 }
279 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100280 g_gb[0].cfg := {
281 nsei := 96,
282 bvci := 196,
283 cell_id := {
284 ra_id := {
285 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100286 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100287 rac := 0
288 },
289 cell_id := 20960
290 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200291 sgsn_role := false,
292 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100293 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200294 g_gb[1].cfg := {
295 nsei := 97,
296 bvci := 210,
297 cell_id := {
298 ra_id := {
299 lai := {
300 mcc_mnc := mcc_mnc, lac := 13200},
301 rac := 0
302 },
303 cell_id := 20961
304 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200305 sgsn_role := false,
306 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200307 };
308 g_gb[2].cfg := {
309 nsei := 98,
310 bvci := 220,
311 cell_id := {
312 ra_id := {
313 lai := {
314 mcc_mnc := mcc_mnc, lac := 13300},
315 rac := 0
316 },
317 cell_id := 20962
318 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200319 sgsn_role := false,
320 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200321 };
Harald Welte96a33b02018-02-04 10:36:22 +0100322
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200323 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200324 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
325 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
326 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200327
328 for (i := 0; i < NUM_RNC; i := i+1) {
329 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
330 f_ran_adapter_start(g_ranap[i]);
331 }
Harald Welte5ac31492018-02-15 20:39:13 +0100332 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100333 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200334 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100335}
Harald Welte96a33b02018-02-04 10:36:22 +0100336
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200337function f_cleanup() runs on test_CT {
338 var integer i;
339 for (i := 0; i < NUM_RNC; i := i+1) {
340 f_ran_adapter_cleanup(g_ranap[i]);
341 }
342 self.stop;
343}
344
Harald Welte26fbb6e2019-04-14 17:32:46 +0200345private function RncUnitdataCallback(RANAP_PDU ranap)
346runs on RAN_Emulation_CT return template RANAP_PDU {
347 var template RANAP_PDU resp := omit;
348
349 log ("RANAP_RncUnitDataCallback");
350 /* answer all RESET with RESET ACK */
351 if (match(ranap, tr_RANAP_Reset)) {
352 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
353 var CN_DomainIndicator dom;
354 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
355 resp := ts_RANAP_ResetAck(dom);
356 }
357 return resp;
358}
359
360const RanOps RNC_RanOps := {
361 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
362 ranap_unitdata_cb := refers(RncUnitdataCallback),
363 ps_domain := true,
364 decode_dtap := true,
365 role_ms := true,
366 protocol := RAN_PROTOCOL_RANAP,
367 transport := RANAP_TRANSPORT_IuCS,
368 use_osmux := false,
369 sccp_addr_local := omit,
370 sccp_addr_peer := omit
371};
372
Harald Welte5ac31492018-02-15 20:39:13 +0100373type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
374
375/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200376function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100377 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100378runs on test_CT return BSSGP_ConnHdlr {
379 var BSSGP_ConnHdlr vc_conn;
380 var SGSN_ConnHdlrNetworkPars net_pars := {
381 expect_ptmsi := true,
382 expect_auth := true,
383 expect_ciph := false
384 };
385 var BSSGP_ConnHdlrPars pars := {
386 imei := f_gen_imei(imsi_suffix),
387 imsi := f_gen_imsi(imsi_suffix),
388 msisdn := f_gen_msisdn(imsi_suffix),
389 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100390 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100391 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100392 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100393 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200394 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 +0200395 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100396 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100397 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200398 t_guard := t_guard,
399 sccp_addr_local := g_ranap[0].sccp_addr_own,
400 sccp_addr_peer := g_ranap[0].sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100401 };
402
403 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200404 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
405 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
406 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
407 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
408 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
409 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100410
Harald Welte26fbb6e2019-04-14 17:32:46 +0200411 /* FIXME: support multiple RNCs */
412 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
413 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
414
Harald Welte5ac31492018-02-15 20:39:13 +0100415 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
416 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
417
Harald Welteeded9ad2018-02-17 20:57:34 +0100418 connect(vc_conn:GTP, vc_GTP:CLIENT);
419 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
420
Harald Welte5ac31492018-02-15 20:39:13 +0100421 vc_conn.start(f_handler_init(fn, id, pars));
422 return vc_conn;
423}
424
Harald Welte62e29582018-02-16 21:17:11 +0100425private altstep as_Tguard() runs on BSSGP_ConnHdlr {
426 [] g_Tguard.timeout {
427 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200428 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100429 }
430}
431
Harald Welte5ac31492018-02-15 20:39:13 +0100432/* first function called in every ConnHdlr */
433private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
434runs on BSSGP_ConnHdlr {
435 /* do some common stuff like setting up g_pars */
436 g_pars := pars;
437
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200438 llc := f_llc_create(false);
439
Harald Welte5ac31492018-02-15 20:39:13 +0100440 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200441 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100442 /* tell GSUP dispatcher to send this IMSI to us */
443 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100444 /* tell GTP dispatcher to send this IMSI to us */
445 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100446
Harald Welte62e29582018-02-16 21:17:11 +0100447 g_Tguard.start(pars.t_guard);
448 activate(as_Tguard());
449
Harald Welte5ac31492018-02-15 20:39:13 +0100450 /* call the user-supplied test case function */
451 fn.apply(id);
452 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100453}
454
455/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100456 * Detach without Attach
457 * SM procedures without attach / RAU
458 * ATTACH / RAU
459 ** with / without authentication
460 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100461 * re-transmissions of LLC frames
462 * PDP Context activation
463 ** with different GGSN config in SGSN VTY
464 ** with different PDP context type (v4/v6/v46)
465 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100466 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100467 */
468
469testcase TC_wait_ns_up() runs on test_CT {
470 f_init();
471 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200472 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100473}
474
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200475friend function is_gb(integer gb_idx) return boolean {
476 return gb_idx < NUM_GB;
477}
478friend function is_iu(integer gb_idx) return boolean {
479 return gb_idx >= NUM_GB;
480}
481
Harald Weltea05b8072019-04-23 22:35:05 +0200482function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
483 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
484 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
485}
486
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200487private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200488 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
489 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
490 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200491 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200492}
493
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200494/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
495function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
496 log("Sending InitialUE: ", l3_mo);
497 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
498 var RANAP_PDU ranap;
499 var LAI lai := {
500 pLMNidentity := '62F224'O,
501 lAC := '1234'O,
502 iE_Extensions := omit
503 };
504 var SAI sai := {
505 pLMNidentity := lai.pLMNidentity,
506 lAC := lai.lAC,
507 sAC := '0000'O, /* FIXME */
508 iE_Extensions := omit
509 };
510 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
511 var GlobalRNC_ID grnc_id := {
512 pLMNidentity := lai.pLMNidentity,
513 rNC_ID := 2342 /* FIXME */
514 };
515
516 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
517 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
518 alt {
519 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
520 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
521 setverdict(fail, "DISC.ind from SCCP");
522 mtc.stop;
523 }
524 }
525}
526
527/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
528function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
529 if (is_iu(gb_index)) {
530 if (g_pars.rnc_send_initial_ue) {
531 g_pars.rnc_send_initial_ue := false;
532 f_send_l3_initial_ue(l3_mo);
533 } else {
534 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
535 }
536 } else {
537 f_send_l3_gmm_llc(l3_mo, gb_index);
538 }
539}
540
Harald Welteca362462019-05-02 20:11:21 +0200541altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100542 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200543 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100544 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200545 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100546 repeat;
547 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200548 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
549 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
550 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
551 repeat;
552 }
553 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100554 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200555 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
556 repeat;
557 }
558 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
559 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
560 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100561 repeat;
562 }
563}
Harald Welte96a33b02018-02-04 10:36:22 +0100564
Harald Welteca362462019-05-02 20:11:21 +0200565/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
566function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
567runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200568 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200569 var PDU_L3_SGSN_MS l3_mt;
570 alt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200571 [is_gb(gb_idx)] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
572 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
573 l3_mt := mt.dtap;
574 }
Harald Welteca362462019-05-02 20:11:21 +0200575 }
576 return l3_mt;
577}
578
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200579/* perform GMM authentication (if expected).
580 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
581 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200582function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100583 var PDU_L3_MS_SGSN l3_mo;
584 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200585 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100586 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200587 var GSUP_IE auth_tuple;
588 var template AuthenticationParameterAUTNTLV autn;
589
590 if (umts_aka_challenge) {
591 g_pars.vec := f_gen_auth_vec_3g();
592 autn := {
593 elementIdentifier := '28'O,
594 lengthIndicator := lengthof(g_pars.vec.autn),
595 autnValue := g_pars.vec.autn
596 };
597
598 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
599 g_pars.vec.sres,
600 g_pars.vec.kc,
601 g_pars.vec.ik,
602 g_pars.vec.ck,
603 g_pars.vec.autn,
604 g_pars.vec.res));
605 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
606 } else {
607 g_pars.vec := f_gen_auth_vec_2g();
608 autn := omit;
609 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
610 g_pars.vec.sres,
611 g_pars.vec.kc));
612 log("GSUP sends only 2G auth tuple", auth_tuple);
613 }
Harald Welteca362462019-05-02 20:11:21 +0200614
Harald Welte5ac31492018-02-15 20:39:13 +0100615 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
616 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200617
618 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
619 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200620 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100621 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200622 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
623
624 if (umts_aka_challenge and not force_gsm_sres) {
625 /* set UMTS response instead */
626 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
627 valueField := substr(g_pars.vec.res, 0, 4)
628 };
629 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
630 elementIdentifier := '21'O,
631 lengthIndicator := lengthof(g_pars.vec.res) - 4,
632 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
633 };
634 }
635
636 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100637 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
638 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
639 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
640 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
641 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200642 f_send_l3(l3_mo, gb_idx);
643
644 /* Security Mode Command + Complete on Iu case */
645 if (is_iu(gb_idx)) {
646 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
647 key_sts := ?)) {
648 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
649 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
650 }
651 }
Harald Welte76dee092018-02-16 22:12:59 +0100652 } else {
653 /* wait for identity procedure */
654 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100655 }
Harald Welte76dee092018-02-16 22:12:59 +0100656
Harald Welte5ac31492018-02-15 20:39:13 +0100657 deactivate(di);
658}
659
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200660function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100661 g_pars.p_tmsi := p_tmsi;
662 /* update TLLI */
663 g_pars.tlli_old := g_pars.tlli;
664 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200665 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100666}
667
Harald Welte04683d02018-02-16 22:43:45 +0100668function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
669 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100670 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200671 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100672 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200673 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200674 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100675 }
Harald Welte04683d02018-02-16 22:43:45 +0100676 g_pars.ra := aa.routingAreaIdentification;
677 if (ispresent(aa.allocatedPTMSI)) {
678 if (not g_pars.net.expect_ptmsi) {
679 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200680 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100681 }
Harald Weltef70997d2018-02-17 10:11:19 +0100682 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100683 }
684 if (ispresent(aa.msIdentity)) {
685 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200686 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100687 }
688 /* P-TMSI.sig */
689 if (ispresent(aa.ptmsiSignature)) {
690 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
691 }
692 /* updateTimer */
693 // aa.readyTimer
694 /* T3302, T3319, T3323, T3312_ext, T3324 */
695}
696
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200697function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100698 /* mandatory IE */
699 g_pars.ra := ra.routingAreaId;
700 if (ispresent(ra.allocatedPTMSI)) {
701 if (not g_pars.net.expect_ptmsi) {
702 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200703 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100704 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200705 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100706 }
707 if (ispresent(ra.msIdentity)) {
708 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200709 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100710 }
711 /* P-TMSI.sig */
712 if (ispresent(ra.ptmsiSignature)) {
713 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
714 }
715 /* updateTimer */
716 // aa.readyTimer
717 /* T3302, T3319, T3323, T3312_ext, T3324 */
718}
719
720
Harald Welte5a4fa042018-02-16 20:59:21 +0100721function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
722 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
723}
724
Harald Welte23178c52018-02-17 09:36:33 +0100725/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100726private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100727 if (ispresent(g_pars.p_tmsi)) {
728 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
729 } else {
730 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
731 }
732}
733
Harald Welte311ec272018-02-17 09:40:03 +0100734private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100735 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100736 /* Expect MSC to perform LU with HLR */
737 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100738 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
739 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
740 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100741 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
742 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
743}
744
Harald Welteca362462019-05-02 20:11:21 +0200745friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100746 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200747 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 +0200748 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100749
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200750 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
751 * 3G auth vectors */
752 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
753 /* The thing is, if the solSACapability is 'omit', then the
754 * revisionLevelIndicatior is at the wrong place! */
755 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
756
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200757 f_send_l3(attach_req, gb_idx);
Harald Welteca362462019-05-02 20:11:21 +0200758 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200759 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100760 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100761
Harald Welteca362462019-05-02 20:11:21 +0200762 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
763 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
764
Harald Welte04683d02018-02-16 22:43:45 +0100765 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200766 f_send_l3(ts_GMM_ATTACH_COMPL, gb_idx);
767
768 /* IuPS case: Expect Iu Release */
769 if (is_iu(gb_idx)) {
770 as_iu_release_compl_disc();
771 }
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200772}
773
774private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
775 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100776 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100777}
778
779testcase TC_attach() runs on test_CT {
780 var BSSGP_ConnHdlr vc_conn;
781 f_init();
782 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200783 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100784 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200785 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100786}
787
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100788testcase TC_attach_mnc3() runs on test_CT {
789 var BSSGP_ConnHdlr vc_conn;
790 f_init('023042'H);
791 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200792 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100793 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200794 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100795}
796
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200797private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
798 f_gmm_attach(true, false);
799 setverdict(pass);
800}
801testcase TC_attach_umts_aka_umts_res() runs on test_CT {
802 var BSSGP_ConnHdlr vc_conn;
803 f_init();
804 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200805 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200806 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200807 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200808}
809
810private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
811 f_gmm_attach(true, true);
812 setverdict(pass);
813}
814testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
815 var BSSGP_ConnHdlr vc_conn;
816 f_init();
817 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200818 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200819 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200820 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200821}
822
Harald Welte5b7c8122018-02-16 21:48:17 +0100823/* MS never responds to ID REQ, expect ATTACH REJECT */
824private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100825 var RoutingAreaIdentificationV old_ra := f_random_RAI();
826
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200827 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100828 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200829 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100830 /* don't send ID Response */
831 repeat;
832 }
Harald Welte955aa942019-05-03 01:29:29 +0200833 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100834 setverdict(pass);
835 }
Harald Welte955aa942019-05-03 01:29:29 +0200836 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100837 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200838 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100839 }
840 }
841}
842testcase TC_attach_auth_id_timeout() runs on test_CT {
843 var BSSGP_ConnHdlr vc_conn;
844 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200845 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 +0100846 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200847 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100848}
849
850/* HLR never responds to SAI REQ, expect ATTACH REJECT */
851private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100852 var RoutingAreaIdentificationV old_ra := f_random_RAI();
853
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200854 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100855 alt {
856 [] as_mm_identity();
857 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
858 }
859 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200860 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100861 setverdict(pass);
862}
863testcase TC_attach_auth_sai_timeout() runs on test_CT {
864 var BSSGP_ConnHdlr vc_conn;
865 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200866 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100867 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200868 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100869}
870
Harald Weltefe253882018-02-17 09:25:00 +0100871/* HLR rejects SAI, expect ATTACH REJECT */
872private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100873 var RoutingAreaIdentificationV old_ra := f_random_RAI();
874
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200875 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100876 alt {
877 [] as_mm_identity();
878 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
879 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
880 }
881 }
Harald Welte955aa942019-05-03 01:29:29 +0200882 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100883 setverdict(pass);
884}
885testcase TC_attach_auth_sai_reject() runs on test_CT {
886 var BSSGP_ConnHdlr vc_conn;
887 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200888 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100889 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200890 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100891}
892
Harald Welte5b7c8122018-02-16 21:48:17 +0100893/* HLR never responds to UL REQ, expect ATTACH REJECT */
894private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200895 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100896 var RoutingAreaIdentificationV old_ra := f_random_RAI();
897
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200898 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100899 f_gmm_auth();
900 /* Expect MSC to perform LU with HLR */
901 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
902 /* Never follow-up with ISD_REQ or UL_RES */
903 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200904 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100905 setverdict(pass);
906 }
Harald Welte955aa942019-05-03 01:29:29 +0200907 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
908 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100909 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200910 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100911 }
912 }
913}
914testcase TC_attach_gsup_lu_timeout() runs on test_CT {
915 var BSSGP_ConnHdlr vc_conn;
916 f_init();
917 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200918 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100919 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200920 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100921}
922
Harald Welteb7c14e92018-02-17 09:29:16 +0100923/* HLR rejects UL REQ, expect ATTACH REJECT */
924private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200925 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100926 var RoutingAreaIdentificationV old_ra := f_random_RAI();
927
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200928 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100929 f_gmm_auth();
930 /* Expect MSC to perform LU with HLR */
931 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
932 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
933 }
934 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200935 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100936 setverdict(pass);
937 }
Harald Welte955aa942019-05-03 01:29:29 +0200938 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
939 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100940 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200941 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100942 }
943 }
944}
945testcase TC_attach_gsup_lu_reject() runs on test_CT {
946 var BSSGP_ConnHdlr vc_conn;
947 f_init();
948 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200949 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100950 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200951 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100952}
953
954
Harald Welte3823e2e2018-02-16 21:53:48 +0100955/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
956private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200957 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100958 var RoutingAreaIdentificationV old_ra := f_random_RAI();
959
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200960 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100961 f_gmm_auth();
962 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100963 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100964
Harald Welte955aa942019-05-03 01:29:29 +0200965 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
966 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100967 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200968 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100969 setverdict(pass);
970}
Harald Welte3823e2e2018-02-16 21:53:48 +0100971testcase TC_attach_combined() runs on test_CT {
972 var BSSGP_ConnHdlr vc_conn;
973 f_init();
974 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200975 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100976 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200977 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +0100978}
979
Harald Welte76dee092018-02-16 22:12:59 +0100980/* Attempt of GPRS ATTACH in 'accept all' mode */
981private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200982 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100983 var RoutingAreaIdentificationV old_ra := f_random_RAI();
984
985 g_pars.net.expect_auth := false;
986
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200987 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100988 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +0200989 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
990 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100991 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200992 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100993 setverdict(pass);
994}
995testcase TC_attach_accept_all() runs on test_CT {
996 var BSSGP_ConnHdlr vc_conn;
997 f_init();
998 f_sleep(1.0);
999 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001000 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001001 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001002 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001003}
Harald Welte5b7c8122018-02-16 21:48:17 +01001004
Harald Welteb2124b22018-02-16 22:26:56 +01001005/* Attempt of GPRS ATTACH in 'accept all' mode */
1006private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001007 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1008
1009 /* Simulate a foreign IMSI */
1010 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001011 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001012
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 Welteb2124b22018-02-16 22:26:56 +01001016 alt {
1017 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001018 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001019 setverdict(pass);
1020 }
Harald Welte955aa942019-05-03 01:29:29 +02001021 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001022 setverdict(pass);
1023 }
Harald Welte955aa942019-05-03 01:29:29 +02001024 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001025 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001026 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001027 }
Harald Welteb2124b22018-02-16 22:26:56 +01001028 }
1029}
1030testcase TC_attach_closed() runs on test_CT {
1031 var BSSGP_ConnHdlr vc_conn;
1032 f_init();
1033 f_sleep(1.0);
1034 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1035 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001036 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001037 vc_conn.done;
1038 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001039 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001040 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001041 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001042}
1043
Harald Welte04683d02018-02-16 22:43:45 +01001044/* Routing Area Update from Unknown TLLI -> REJECT */
1045private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001046 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1047
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001048 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 +01001049 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001050 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +01001051 setverdict(pass);
1052 }
1053 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001054 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001055 }
1056}
1057testcase TC_rau_unknown() runs on test_CT {
1058 var BSSGP_ConnHdlr vc_conn;
1059 f_init();
1060 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001061 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001062 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001063 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001064}
1065
Harald Welte91636de2018-02-17 10:16:14 +01001066private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001067 /* first perform regular attach */
1068 f_TC_attach(id);
1069
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001070 f_routing_area_update(g_pars.ra);
1071
Harald Welte91636de2018-02-17 10:16:14 +01001072}
1073testcase TC_attach_rau() runs on test_CT {
1074 var BSSGP_ConnHdlr vc_conn;
1075 f_init();
1076 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001077 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001078 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001079 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001080}
Harald Welte04683d02018-02-16 22:43:45 +01001081
Harald Welte6abb9fe2018-02-17 15:24:48 +01001082/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001083function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001084 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001085 timer T := 5.0;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001086 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001087 if (expect_purge) {
1088 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1089 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1090 }
1091 T.start;
1092 alt {
1093 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1094 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001095 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001096 }
Harald Welte955aa942019-05-03 01:29:29 +02001097 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001098 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001099 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001100 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001101 /* TODO: check if any PDP contexts are deactivated on network side? */
1102 }
1103 [power_off] T.timeout {
1104 setverdict(pass);
1105 }
Harald Welte955aa942019-05-03 01:29:29 +02001106 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001107 g_pars.ra := omit;
1108 setverdict(pass);
1109 /* TODO: check if any PDP contexts are deactivated on network side? */
1110 }
Harald Welte955aa942019-05-03 01:29:29 +02001111 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001112 if (power_off) {
1113 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1114 } else {
1115 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1116 }
1117 mtc.stop;
1118 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001119 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001120 }
1121}
1122
1123/* IMSI DETACH (non-power-off) for unknown TLLI */
1124private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1125 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1126}
1127testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1128 var BSSGP_ConnHdlr vc_conn;
1129 f_init();
1130 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001131 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001132 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001133 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001134}
1135
1136/* IMSI DETACH (power-off) for unknown TLLI */
1137private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1138 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1139}
1140testcase TC_detach_unknown_poweroff() runs on test_CT {
1141 var BSSGP_ConnHdlr vc_conn;
1142 f_init();
1143 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001144 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001145 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001146 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001147}
1148
1149/* IMSI DETACH (non-power-off) for known TLLI */
1150private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1151 /* first perform regular attach */
1152 f_TC_attach(id);
1153
1154 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1155}
1156testcase TC_detach_nopoweroff() runs on test_CT {
1157 var BSSGP_ConnHdlr vc_conn;
1158 f_init();
1159 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001160 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001161 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001162 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001163}
1164
1165/* IMSI DETACH (power-off) for known TLLI */
1166private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1167 /* first perform regular attach */
1168 f_TC_attach(id);
1169
1170 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1171}
1172testcase TC_detach_poweroff() runs on test_CT {
1173 var BSSGP_ConnHdlr vc_conn;
1174 f_init();
1175 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001176 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001177 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001178 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001179}
1180
Harald Welteeded9ad2018-02-17 20:57:34 +01001181type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001182 BIT3 tid, /* L3 Transaction ID */
1183 BIT4 nsapi, /* SNDCP NSAPI */
1184 BIT4 sapi, /* LLC SAPI */
1185 QoSV qos, /* QoS parameters */
1186 PDPAddressV addr, /* IP address */
1187 octetstring apn optional, /* APN name */
1188 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1189 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001190 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001191 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001192
Harald Welte822f9102018-02-18 20:39:06 +01001193 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1194 OCT4 ggsn_tei_u, /* GGSN TEI User */
1195 octetstring ggsn_ip_c, /* GGSN IP Control */
1196 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001197 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001198
Harald Welte822f9102018-02-18 20:39:06 +01001199 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1200 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1201 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1202 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001203};
1204
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001205
1206private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1207 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1208 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1209 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1210 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1211 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1212 f_gtp_register_teid(apars.ggsn_tei_c);
1213 f_gtp_register_teid(apars.ggsn_tei_u);
1214}
1215
Harald Weltef7191672019-05-02 20:37:23 +02001216function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1217runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001218 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1219 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001220 var template Recovery_gtpc recovery := omit;
1221
1222 if (send_recovery) {
1223 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1224 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001225
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001226 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001227 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001228 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1229 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1230 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1231 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1232 apars.sgsn_tei_c, apars.gtp_resp_cause,
1233 apars.ggsn_tei_c, apars.ggsn_tei_u,
1234 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001235 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1236 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001237 }
1238 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001239 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001240 setverdict(pass);
1241 }
Harald Welte955aa942019-05-03 01:29:29 +02001242 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001243 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001244 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001245 }
Harald Welte955aa942019-05-03 01:29:29 +02001246 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001247 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001248 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001249 }
Harald Welte955aa942019-05-03 01:29:29 +02001250 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001251 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1252 mtc.stop;
1253 }
Harald Welte955aa942019-05-03 01:29:29 +02001254 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001255 setverdict(pass);
1256 }
Harald Weltef7191672019-05-02 20:37:23 +02001257 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001258 }
1259}
1260
Harald Weltef7191672019-05-02 20:37:23 +02001261function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1262runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001263 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1264 var Gtp1cUnitdata g_ud;
1265
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001266 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001267 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1268 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001269 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001270 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1271 }
1272 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001273 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001274 setverdict(pass);
1275 }
Harald Weltef7191672019-05-02 20:37:23 +02001276 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001277 }
1278}
1279
Harald Weltef7191672019-05-02 20:37:23 +02001280function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1281runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001282 var Gtp1cUnitdata g_ud;
1283 var integer seq_nr := 23;
1284 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1285
Harald Weltef7191672019-05-02 20:37:23 +02001286 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001287 if (error_ind) {
1288 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1289 } else {
1290 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1291 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001292
1293 timer T := 5.0;
1294 T.start;
1295
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001296 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001297 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001298 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001299 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001300 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1301 repeat;
1302 }
1303 [] T.timeout {
1304 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1305 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001306 }
1307}
1308
Harald Welte6f203162018-02-18 22:04:55 +01001309
Harald Welteeded9ad2018-02-17 20:57:34 +01001310/* Table 10.5.156/3GPP TS 24.008 */
1311template (value) QoSV t_QosDefault := {
1312 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1313 delayClass := '100'B, /* best effort */
1314 spare1 := '00'B,
1315 precedenceClass := '010'B, /* normal */
1316 spare2 := '0'B,
1317 peakThroughput := '0000'B, /* subscribed */
1318 meanThroughput := '00000'B, /* subscribed */
1319 spare3 := '000'B,
1320 deliverErroneusSDU := omit,
1321 deliveryOrder := omit,
1322 trafficClass := omit,
1323 maxSDUSize := omit,
1324 maxBitrateUplink := omit,
1325 maxBitrateDownlink := omit,
1326 sduErrorRatio := omit,
1327 residualBER := omit,
1328 trafficHandlingPriority := omit,
1329 transferDelay := omit,
1330 guaranteedBitRateUplink := omit,
1331 guaranteedBitRateDownlink := omit,
1332 sourceStatisticsDescriptor := omit,
1333 signallingIndication := omit,
1334 spare4 := omit,
1335 maxBitrateDownlinkExt := omit,
1336 guaranteedBitRateDownlinkExt := omit,
1337 maxBitrateUplinkExt := omit,
1338 guaranteedBitRateUplinkExt := omit,
1339 maxBitrateDownlinkExt2 := omit,
1340 guaranteedBitRateDownlinkExt2 := omit,
1341 maxBitrateUplinkExt2 := omit,
1342 guaranteedBitRateUplinkExt2 := omit
1343}
1344
1345/* 10.5.6.4 / 3GPP TS 24.008 */
1346template (value) PDPAddressV t_AddrIPv4dyn := {
1347 pdpTypeOrg := '0001'B, /* IETF */
1348 spare := '0000'B,
1349 pdpTypeNum := '21'O, /* IPv4 */
1350 addressInfo := omit
1351}
1352template (value) PDPAddressV t_AddrIPv6dyn := {
1353 pdpTypeOrg := '0001'B, /* IETF */
1354 spare := '0000'B,
1355 pdpTypeNum := '53'O, /* IPv6 */
1356 addressInfo := omit
1357}
1358
Harald Welte37692d82018-02-18 15:21:34 +01001359template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001360 tid := '000'B,
1361 nsapi := '0101'B, /* < 5 are reserved */
1362 sapi := '0011'B, /* 3/5/9/11 */
1363 qos := t_QosDefault,
1364 addr := t_AddrIPv4dyn,
1365 apn := omit,
1366 pco := omit,
1367 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001368 gtp_resp_cause := int2oct(128, 1),
1369 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001370
1371 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001372 ggsn_tei_c := f_rnd_octstring(4),
1373 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001374 ggsn_ip_c := f_inet_addr(ggsn_ip),
1375 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001376 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001377
Harald Welteeded9ad2018-02-17 20:57:34 +01001378 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001379 sgsn_tei_u := omit,
1380 sgsn_ip_c := omit,
1381 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001382}
1383
Harald Welte37692d82018-02-18 15:21:34 +01001384template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1385 connId := 1,
1386 remName := f_inet_ntoa(ip),
1387 remPort := GTP1U_PORT
1388}
1389
1390template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1391 connId := 1,
1392 remName := f_inet_ntoa(ip),
1393 remPort := GTP1C_PORT
1394}
1395
1396private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1397 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1398 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1399}
1400
Harald Weltef7191672019-05-02 20:37:23 +02001401private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001402 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001403 repeat;
1404 }
1405}
1406
1407template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1408 pDU_SN_UNITDATA := {
1409 nsapi := nsapi,
1410 moreBit := ?,
1411 snPduType := '1'B,
1412 firstSegmentIndicator := ?,
1413 spareBit := ?,
1414 pcomp := ?,
1415 dcomp := ?,
1416 npduNumber := ?,
1417 segmentNumber := ?,
1418 npduNumberContinued := ?,
1419 dataSegmentSnUnitdataPdu := payload
1420 }
1421}
1422
1423/* simple case: single segment, no compression */
1424template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1425 pDU_SN_UNITDATA := {
1426 nsapi := nsapi,
1427 moreBit := '0'B,
1428 snPduType := '1'B,
1429 firstSegmentIndicator := '1'B,
1430 spareBit := '0'B,
1431 pcomp := '0000'B,
1432 dcomp := '0000'B,
1433 npduNumber := '0000'B,
1434 segmentNumber := '0000'B,
1435 npduNumberContinued := '00'O,
1436 dataSegmentSnUnitdataPdu := payload
1437 }
1438}
1439
1440/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001441private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1442runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001443 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1444 f_gtpu_send(apars, payload);
1445 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1446 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001447 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001448 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1449 [] BSSGP[gb_idx].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001450 }
1451}
1452
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001453/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001454private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1455runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001456 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1457 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1458 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001459 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001460 /* Expect PDU via GTP from SGSN on simulated GGSN */
1461 alt {
1462 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1463 }
1464}
1465
Harald Welteeded9ad2018-02-17 20:57:34 +01001466private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001467 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001468
1469 /* first perform regular attach */
1470 f_TC_attach(id);
1471
1472 f_pdp_ctx_act(apars);
1473}
1474testcase TC_attach_pdp_act() runs on test_CT {
1475 var BSSGP_ConnHdlr vc_conn;
1476 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001477 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001478 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001479 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001480}
Harald Welteb2124b22018-02-16 22:26:56 +01001481
Harald Welte835b15f2018-02-18 14:39:11 +01001482/* PDP Context activation for not-attached subscriber; expect fail */
1483private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001484 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001485 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 +01001486 apars.apn, apars.pco));
1487 alt {
1488 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001489 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001490 setverdict(pass);
1491 }
1492 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1493 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001494 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001495 }
Harald Welte955aa942019-05-03 01:29:29 +02001496 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001497 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001498 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001499 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001500 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001501 }
1502}
1503testcase TC_pdp_act_unattached() runs on test_CT {
1504 var BSSGP_ConnHdlr vc_conn;
1505 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001506 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001507 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001508 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001509}
1510
Harald Welte37692d82018-02-18 15:21:34 +01001511/* ATTACH + PDP CTX ACT + user plane traffic */
1512private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1513 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1514
1515 /* first perform regular attach */
1516 f_TC_attach(id);
1517 /* then activate PDP context */
1518 f_pdp_ctx_act(apars);
1519 /* then transceive a downlink PDU */
1520 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1521 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1522}
1523testcase TC_attach_pdp_act_user() runs on test_CT {
1524 var BSSGP_ConnHdlr vc_conn;
1525 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001526 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001527 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001528 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001529}
1530
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001531/* ATTACH + PDP CTX ACT; reject from GGSN */
1532private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1533 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1534
1535 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1536 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1537
1538 /* first perform regular attach */
1539 f_TC_attach(id);
1540 /* then activate PDP context */
1541 f_pdp_ctx_act(apars);
1542}
1543testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1544 var BSSGP_ConnHdlr vc_conn;
1545 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001546 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001547 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001548 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001549}
Harald Welte835b15f2018-02-18 14:39:11 +01001550
Harald Welte6f203162018-02-18 22:04:55 +01001551/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1552private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1553 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1554
1555 /* first perform regular attach */
1556 f_TC_attach(id);
1557 /* then activate PDP context */
1558 f_pdp_ctx_act(apars);
1559 /* then transceive a downlink PDU */
1560 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1561 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1562
1563 f_pdp_ctx_deact_mo(apars, '00'O);
1564}
1565testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1566 var BSSGP_ConnHdlr vc_conn;
1567 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001568 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 +01001569 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001570 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001571}
1572
Harald Welte57b9b7f2018-02-18 22:28:13 +01001573/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1574private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1575 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1576
1577 /* first perform regular attach */
1578 f_TC_attach(id);
1579 /* then activate PDP context */
1580 f_pdp_ctx_act(apars);
1581 /* then transceive a downlink PDU */
1582 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1583 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1584
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001585 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001586}
1587testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1588 var BSSGP_ConnHdlr vc_conn;
1589 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001590 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 +01001591 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001592 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001593}
1594
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001595/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1596private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1597 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1598 var Gtp1cUnitdata g_ud;
1599 var integer i;
1600 var OCT1 cause_regular_deact := '24'O;
1601
1602 /* first perform regular attach + PDP context act */
1603 f_TC_attach(id);
1604 f_pdp_ctx_act(apars);
1605
1606 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1607 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1608
1609 for (i := 0; i < 2; i := i+1) {
1610 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1611 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1612 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1613 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1614 }
1615 }
1616
1617 alt {
1618 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1619 setverdict(pass);
1620 }
1621 [] as_xid(apars, 0);
1622 }
1623
1624 /* Make sure second DeactPdpAccept is sent: */
1625 timer T := 2.0;
1626 T.start;
1627 alt {
1628 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1629 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1630 }
1631 [] T.timeout {
1632 setverdict(pass);
1633 }
1634 }
1635
1636 setverdict(pass);
1637}
1638testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1639 var BSSGP_ConnHdlr vc_conn;
1640 f_init();
1641 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1642 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001643 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001644}
1645
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001646/* ATTACH + ATTACH (2nd) */
1647private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1648 g_pars.t_guard := 5.0;
1649
1650 /* first perform regular attach */
1651 f_TC_attach(id);
1652
1653 /* second to perform regular attach */
1654 f_TC_attach(id);
1655}
1656
1657
1658testcase TC_attach_second_attempt() runs on test_CT {
1659 var BSSGP_ConnHdlr vc_conn;
1660 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001661 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001662 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001663 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001664}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001665
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001666private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1667 var Gtp1cUnitdata g_ud;
1668 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1669 var integer seq_nr;
1670
1671 /* first perform regular attach */
1672 f_TC_attach(id);
1673 /* then activate PDP context */
1674 f_pdp_ctx_act(apars);
1675
1676 /* Wait to receive first echo request and send initial Restart counter */
1677 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1678 BSSGP[0].clear;
1679 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1680 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1681 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1682 }
1683
1684 /* At some point next echo request not answered will timeout and SGSN
1685 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1686 timer T := 3.0 * 6.0 + 16.0;
1687 T.start;
1688 alt {
1689 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1690 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1691 setverdict(pass);
1692 }
1693 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1694 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1695 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1696 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1697 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1698 repeat;
1699 }
1700 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1701 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1702 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1703 repeat;
1704 }
1705 [] T.timeout {
1706 setverdict(fail, "BSSGP DeactPdpReq not received");
1707 mtc.stop;
1708 }
1709 [] as_xid(apars);
1710 }
1711 T.stop
1712
1713 setverdict(pass);
1714}
1715/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1716testcase TC_attach_echo_timeout() runs on test_CT {
1717 var BSSGP_ConnHdlr vc_conn;
1718 g_use_echo := true;
1719 f_init();
1720 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1721 vc_conn.done;
1722 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001723 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001724}
1725
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001726private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001727 var Gtp1cUnitdata g_ud;
1728 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1729
1730 /* first perform regular attach */
1731 f_TC_attach(id);
1732 /* Activate a pdp context against the GGSN */
1733 f_pdp_ctx_act(apars);
1734 /* Wait to receive first echo request and send initial Restart counter */
1735 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1736 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1737 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1738 }
1739 /* Wait to receive second echo request and send incremented Restart
1740 counter. This will fake a restarted GGSN, and pdp ctx allocated
1741 should be released by SGSN */
1742 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1743 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1744 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1745 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1746 }
1747 var OCT1 cause_network_failure := int2oct(38, 1)
1748 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001749 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001750 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001751 setverdict(pass);
1752 }
1753 [] as_xid(apars);
1754 }
1755 setverdict(pass);
1756}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001757/* ATTACH + trigger Recovery procedure through EchoResp */
1758testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001759 var BSSGP_ConnHdlr vc_conn;
1760 g_use_echo := true
1761 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001762 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 +02001763 vc_conn.done;
1764 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001765 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001766}
1767
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001768private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1769 var Gtp1cUnitdata g_ud;
1770 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1771 var integer seq_nr := 23;
1772 var GtpPeer peer;
1773 /* first perform regular attach */
1774 f_TC_attach(id);
1775
1776 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1777 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1778 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1779 f_pdp_ctx_act(apars, true);
1780
1781 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1782/* received. */
1783 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1784
1785 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1786 would be great to have an active pdp context here before triggering
1787 Recovery, and making sure the the DEACT request is sent by the SGSN.
1788 */
1789
1790 /* Activate a pdp context against the GGSN, send incremented Recovery
1791 IE. This should trigger the recovery path, but still this specific
1792 CTX activation should work. */
1793 apars.exp_rej_cause := omit; /* default value for tests */
1794 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1795 f_pdp_ctx_act(apars, true);
1796
1797 setverdict(pass);
1798}
1799/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1800testcase TC_attach_restart_ctr_create() runs on test_CT {
1801 var BSSGP_ConnHdlr vc_conn;
1802 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001803 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 +02001804 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001805 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001806}
1807
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001808/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1809private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1810 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1811 var integer seq_nr := 23;
1812 var GtpPeer peer;
1813 var integer i;
1814
1815 /* first perform regular attach */
1816 f_TC_attach(id);
1817 /* then activate PDP context */
1818 f_pdp_ctx_act(apars);
1819
Alexander Couzens0e510e62018-07-28 23:06:00 +02001820 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001821 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1822 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1823
1824 for (i := 0; i < 5; i := i+1) {
1825 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001826 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001827 [] as_xid(apars);
1828 }
1829 }
1830
1831 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1832
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001833 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001834 setverdict(pass);
1835}
1836testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1837 var BSSGP_ConnHdlr vc_conn;
1838 f_init();
1839 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001840 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 +02001841 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001842 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001843}
1844
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001845/* ATTACH + PDP CTX ACT dropped + retrans */
1846private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1847 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1848 var Gtp1cUnitdata g_ud_first, g_ud_second;
1849 /* first perform regular attach */
1850 f_TC_attach(id);
1851
1852 /* then activate PDP context on the Gb side */
1853 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1854 apars.apn, apars.pco), 0);
1855
1856 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1857 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1858 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1859 if (g_ud_first != g_ud_second) {
1860 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1861 mtc.stop;
1862 }
1863 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1864 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1865 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1866 apars.sgsn_tei_c, apars.gtp_resp_cause,
1867 apars.ggsn_tei_c, apars.ggsn_tei_u,
1868 apars.nsapi,
1869 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1870 omit, omit));
1871 }
Harald Welte955aa942019-05-03 01:29:29 +02001872 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001873
1874 /* Now the same with Deact */
1875 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1876 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1877 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1878 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1879 if (g_ud_first != g_ud_second) {
1880 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1881 mtc.stop;
1882 }
1883 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1884 BSSGP[0].clear;
1885 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1886 }
1887 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001888 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001889 setverdict(pass);
1890 }
1891 [] as_xid(apars, 0);
1892 }
1893
1894 setverdict(pass);
1895}
1896testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1897 var BSSGP_ConnHdlr vc_conn;
1898 f_init();
1899 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1900 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001901 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001902}
1903
1904/* Test that SGSN GTP response retransmit queue works fine */
1905private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1906 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1907 var integer seq_nr := 23;
1908 var Gtp1cUnitdata g_ud_first, g_ud_second;
1909 var template Gtp1cUnitdata g_delete_req;
1910 /* first perform regular attach + PDP context act */
1911 f_TC_attach(id);
1912 f_pdp_ctx_act(apars);
1913
1914 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1915 BSSGP[0].clear;
1916 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1917 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1918 GTP.send(g_delete_req);
1919 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001920 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001921 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1922 }
1923 [] as_xid(apars, 0);
1924 }
1925 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1926 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1927 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1928 mtc.stop;
1929 }
1930 };
1931
1932 /* Send duplicate DeleteCtxReq */
1933 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1934 GTP.send(g_delete_req);
1935 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1936 if (g_ud_first != g_ud_second) {
1937 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1938 mtc.stop;
1939 }
1940 }
1941
1942 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1943 * is handled differently by SGSN (expect "non-existent" cause) */
1944 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1945 GTP.send(g_delete_req);
1946 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1947 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1948 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1949 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1950 mtc.stop;
1951 }
1952 }
1953
1954 setverdict(pass);
1955}
1956testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1957 var BSSGP_ConnHdlr vc_conn;
1958 f_init();
1959 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1960 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001961 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001962}
1963
Alexander Couzens5e307b42018-05-22 18:12:20 +02001964private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1965 /* MS: perform regular attach */
1966 f_TC_attach(id);
1967
1968 /* HLR: cancel the location request */
1969 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1970 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001971
1972 /* ensure no Detach Request got received */
1973 timer T := 5.0;
1974 T.start;
1975 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001976 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001977 T.stop;
1978 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001979 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001980 }
1981 [] T.timeout {
1982 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001983 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001984 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001985 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001986 repeat;
1987 }
1988 }
1989}
1990
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001991/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1992private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1993 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1994
1995 /* first perform regular attach */
1996 f_TC_attach(id);
1997 /* then activate PDP context */
1998 f_pdp_ctx_act(apars);
1999 /* then transceive a downlink PDU */
2000 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2001
2002 /* Send Error indication as response from upload PDU and expect deact towards MS */
2003 f_pdp_ctx_deact_mt(apars, true);
2004}
2005testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2006 var BSSGP_ConnHdlr vc_conn;
2007 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002008 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 +02002009 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002010 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002011}
2012
Alexander Couzens5e307b42018-05-22 18:12:20 +02002013testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2014 /* MS <-> SGSN: GMM Attach
2015 * HLR -> SGSN: Cancel Location Request
2016 * HLR <- SGSN: Cancel Location Ack
2017 */
2018 var BSSGP_ConnHdlr vc_conn;
2019 f_init();
2020 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002021 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002022 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002023 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002024}
2025
2026
Alexander Couzensc87967a2018-05-22 16:09:54 +02002027private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2028 /* MS: perform regular attach */
2029 f_TC_attach(id);
2030
2031 /* HLR: cancel the location request */
2032 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2033 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2034 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2035
2036 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002037 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002038 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002039
2040 setverdict(pass);
2041}
2042
2043testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2044 /* MS <-> SGSN: GMM Attach
2045 * HLR -> SGSN: Cancel Location Request
2046 * HLR <- SGSN: Cancel Location Ack
2047 * MS <- SGSN: Detach Request
2048 * SGSN-> MS: Detach Complete
2049 */
2050 var BSSGP_ConnHdlr vc_conn;
2051 f_init();
2052 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002053 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002054 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002055 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002056}
2057
2058
Alexander Couzens6c47f292018-05-22 17:09:49 +02002059private function f_hlr_location_cancel_request_unknown_subscriber(
2060 charstring id,
2061 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2062
2063 /* HLR: cancel the location request */
2064 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2065
2066 /* cause 2 = IMSI_UNKNOWN */
2067 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2068
2069 setverdict(pass);
2070}
2071
2072private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002073 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002074}
2075
2076testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2077 /* HLR -> SGSN: Cancel Location Request
2078 * HLR <- SGSN: Cancel Location Error
2079 */
2080
2081 var BSSGP_ConnHdlr vc_conn;
2082 f_init();
2083 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002084 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 +02002085 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002086 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002087}
2088
2089private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002090 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002091}
2092
2093testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2094 /* HLR -> SGSN: Cancel Location Request
2095 * HLR <- SGSN: Cancel Location Error
2096 */
2097
2098 var BSSGP_ConnHdlr vc_conn;
2099 f_init();
2100 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002101 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 +02002102 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002103 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002104}
2105
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002106private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2107 f_TC_attach(id);
2108 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2109}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002110
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002111testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2112 /* MS <-> SGSN: Attach
2113 * MS -> SGSN: Detach Req (Power off)
2114 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2115 */
2116 var BSSGP_ConnHdlr vc_conn;
2117 var integer id := 33;
2118 var charstring imsi := hex2str(f_gen_imsi(id));
2119
2120 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002121 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002122 vc_conn.done;
2123
2124 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002125 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002126}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002127
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002128/* Attempt an attach, but loose the Identification Request (IMEI) */
2129private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2130 var integer count_req := 0;
2131 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2132
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002133 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 +02002134
2135 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002136 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002137 /* break */
2138 }
Harald Welte955aa942019-05-03 01:29:29 +02002139 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002140 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002141 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002142 repeat;
2143 }
Harald Welte955aa942019-05-03 01:29:29 +02002144 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002145 /* ignore ID REQ IMEI */
2146 count_req := count_req + 1;
2147 repeat;
2148 }
2149 }
2150 if (count_req != 5) {
2151 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002152 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002153 }
2154 setverdict(pass);
2155}
2156
2157testcase TC_attach_no_imei_response() runs on test_CT {
2158 /* MS -> SGSN: Attach Request IMSI
2159 * MS <- SGSN: Identity Request IMSI (optional)
2160 * MS -> SGSN: Identity Response IMSI (optional)
2161 * MS <- SGSN: Identity Request IMEI
2162 * MS -x SGSN: no response
2163 * MS <- SGSN: re-send: Identity Request IMEI 4x
2164 * MS <- SGSN: Attach Reject
2165 */
2166 var BSSGP_ConnHdlr vc_conn;
2167 f_init();
2168 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002169 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 +02002170 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002171 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002172}
2173
Alexander Couzens53f20562018-06-12 16:24:12 +02002174/* Attempt an attach, but loose the Identification Request (IMSI) */
2175private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2176 var integer count_req := 0;
2177 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2178
2179 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2180 g_pars.p_tmsi := 'c0000035'O;
2181
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002182 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 +02002183
2184 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002185 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002186 /* break */
2187 }
Harald Welte955aa942019-05-03 01:29:29 +02002188 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002189 /* ignore ID REQ IMSI */
2190 count_req := count_req + 1;
2191 repeat;
2192 }
Harald Welte955aa942019-05-03 01:29:29 +02002193 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002194 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002195 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002196 repeat;
2197 }
2198 }
2199 if (count_req != 5) {
2200 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002201 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002202 }
2203 setverdict(pass);
2204}
2205
2206testcase TC_attach_no_imsi_response() runs on test_CT {
2207 /* MS -> SGSN: Attach Request TMSI (unknown)
2208 * MS <- SGSN: Identity Request IMEI (optional)
2209 * MS -> SGSN: Identity Response IMEI (optional)
2210 * MS <- SGSN: Identity Request IMSI
2211 * MS -x SGSN: no response
2212 * MS <- SGSN: re-send: Identity Request IMSI 4x
2213 * MS <- SGSN: Attach Reject
2214 */
2215 var BSSGP_ConnHdlr vc_conn;
2216 f_init();
2217 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002218 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 +02002219 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002220 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002221}
2222
Alexander Couzenscf818962018-06-05 18:00:00 +02002223private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2224 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2225}
2226
2227testcase TC_attach_check_subscriber_list() runs on test_CT {
2228 /* MS <-> SGSN: Attach
2229 * VTY -> SGSN: Check if MS is in subscriber cache
2230 */
2231 var BSSGP_ConnHdlr vc_conn;
2232 var integer id := 34;
2233 var charstring imsi := hex2str(f_gen_imsi(id));
2234
2235 f_init();
2236 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002237 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002238 vc_conn.done;
2239
2240 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2241 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002242 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002243}
2244
Alexander Couzensf9858652018-06-07 16:14:53 +02002245private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2246 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002247 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002248
2249 /* unregister the old IMSI */
2250 f_bssgp_client_unregister(g_pars.imsi);
2251 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002252 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002253 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002254
2255 /* there is no auth */
2256 g_pars.net.expect_auth := false;
2257
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002258 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002259 f_gmm_auth();
2260 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002261 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002262 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002263 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002264 }
Harald Welte955aa942019-05-03 01:29:29 +02002265 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2266 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002267 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002268 setverdict(pass);
2269 }
2270 }
2271}
Alexander Couzens03d12242018-08-07 16:13:52 +02002272
2273private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2274
2275 f_TC_attach_closed_foreign(id);
2276 f_TC_attach_closed_imsi_added(id);
2277
2278}
2279
2280
Alexander Couzensf9858652018-06-07 16:14:53 +02002281testcase TC_attach_closed_add_vty() runs on test_CT {
2282 /* VTY-> SGSN: policy close
2283 * MS -> SGSN: Attach Request
2284 * MS <- SGSN: Identity Request IMSI
2285 * MS -> SGSN: Identity Response IMSI
2286 * MS <- SGSN: Attach Reject
2287 * VTY-> SGSN: policy imsi-acl add IMSI
2288 * MS -> SGSN: Attach Request
2289 * MS <- SGSN: Identity Request IMSI
2290 * MS -> SGSN: Identity Response IMSI
2291 * MS <- SGSN: Identity Request IMEI
2292 * MS -> SGSN: Identity Response IMEI
2293 * MS <- SGSN: Attach Accept
2294 */
2295 var BSSGP_ConnHdlr vc_conn;
2296 f_init();
2297 f_sleep(1.0);
2298 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2299 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002300 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2301 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002302 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002303 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002304 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002305 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002306}
2307
Alexander Couzens0085bd72018-06-12 19:08:44 +02002308/* Attempt an attach, but never answer a Attach Complete */
2309private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2310 var integer count_req := 0;
2311
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002312 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 +02002313 f_gmm_auth();
2314
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002315 timer T := 10.0;
2316 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002317 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002318 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002319 /* break */
2320 }
Harald Welte955aa942019-05-03 01:29:29 +02002321 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002322 /* ignore */
2323 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002324 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002325 repeat;
2326 }
2327 }
2328 if (count_req != 5) {
2329 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002330 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002331 }
2332 setverdict(pass);
2333}
2334
2335testcase TC_attach_check_complete_resend() runs on test_CT {
2336 /* MS -> SGSN: Attach Request IMSI
2337 * MS <- SGSN: Identity Request *
2338 * MS -> SGSN: Identity Response *
2339 * MS <- SGSN: Attach Complete 5x
2340 */
2341 var BSSGP_ConnHdlr vc_conn;
2342 f_init();
2343 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002344 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 +02002345 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002346 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002347}
2348
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002349private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002350 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002351
2352 /* then send RAU */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002353 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002354 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002355 [] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2356 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002357 f_send_l3(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002358 setverdict(pass);
2359 }
Harald Welte955aa942019-05-03 01:29:29 +02002360 [] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002361 setverdict(fail, "Unexpected RAU Reject");
2362 mtc.stop;
2363 }
2364 [] BSSGP[bssgp].receive { repeat; }
2365 }
2366}
2367
Alexander Couzensbfda9212018-07-31 03:17:33 +02002368private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002369 /* first perform regular attach */
2370 f_TC_attach(id);
2371
2372 /* then send RAU */
2373 f_routing_area_update(g_pars.ra);
2374
2375 /* do another RAU */
2376 f_routing_area_update(g_pars.ra);
2377
2378 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2379}
2380
2381testcase TC_attach_rau_a_a() runs on test_CT {
2382 /* MS <-> SGSN: Successful Attach
2383 * MS -> SGSN: Routing Area Update Request
2384 * MS <- SGSN: Routing Area Update Accept
2385 * MS -> SGSN: Routing Area Update Request
2386 * MS <- SGSN: Routing Area Update Accept
2387 * MS -> SGSN: Detach (PowerOff)
2388 */
2389 var BSSGP_ConnHdlr vc_conn;
2390 f_init();
2391 f_sleep(1.0);
2392 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2393 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002394 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002395}
2396
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002397private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002398 f_TC_attach(id);
2399
2400 log("attach complete sending rau");
2401 f_routing_area_update(g_pars.ra, 0);
2402
2403 log("rau complete unregistering");
2404 f_bssgp_client_unregister(g_pars.imsi);
2405 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2406
2407 log("sending second RAU via different RA");
2408 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2409
2410 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2411}
2412
2413testcase TC_attach_rau_a_b() runs on test_CT {
2414 /* MS <-> SGSN: Successful Attach
2415 * MS -> SGSN: Routing Area _a_ Update Request
2416 * MS <- SGSN: Routing Area _a_ Update Accept
2417 * MS -> SGSN: Routing Area _b_ Update Request
2418 * MS <- SGSN: Routing Area _b_ Update Accept
2419 * MS -> SGSN: Detach (PowerOff)
2420 */
2421 var BSSGP_ConnHdlr vc_conn;
2422 f_init();
2423 f_sleep(1.0);
2424 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2425 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002426 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002427}
2428
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002429private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2430 var integer count_req := 0;
2431 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2432 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002433 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002434
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002435 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002436
2437 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002438 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002439 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2440 mtc.stop;
2441 }
Harald Welte955aa942019-05-03 01:29:29 +02002442 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002443 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002444 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002445 repeat;
2446 }
Harald Welte955aa942019-05-03 01:29:29 +02002447 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002448 /* send out a second GMM_Attach Request.
2449 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2450 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002451 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002452 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002453 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002454 }
2455 }
2456 f_sleep(1.0);
2457
2458 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2459 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002460 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002461 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002462 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002463 repeat;
2464 }
Harald Welte955aa942019-05-03 01:29:29 +02002465 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002466 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2467 mtc.stop;
2468 }
Harald Welte955aa942019-05-03 01:29:29 +02002469 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002470 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2471 mtc.stop;
2472 }
Harald Welte955aa942019-05-03 01:29:29 +02002473 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2474 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002475 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002476 setverdict(pass);
2477 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2478 }
2479 }
2480}
2481
2482testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2483 /* Testing if the SGSN ignore Attach Request with the exact same content */
2484 /* MS -> SGSN: Attach Request IMSI
2485 * MS <- SGSN: Identity Request IMSI (optional)
2486 * MS -> SGSN: Identity Response IMSI (optional)
2487 * MS <- SGSN: Identity Request IMEI
2488 * MS -> SGSN: Attach Request (2nd)
2489 * MS <- SGSN: Identity Response IMEI
2490 * MS <- SGSN: Attach Accept
2491 * MS -> SGSN: Attach Complete
2492 */
2493 var BSSGP_ConnHdlr vc_conn;
2494 f_init();
2495 f_sleep(1.0);
2496 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2497 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2498 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002499 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002500}
2501
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002502private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002503 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2504
2505 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2506
2507 /* send Attach Request */
2508 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2509 * 3G auth vectors */
2510 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2511 /* The thing is, if the solSACapability is 'omit', then the
2512 * revisionLevelIndicatior is at the wrong place! */
2513 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002514 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002515
2516 /* do the auth */
2517 var PDU_L3_MS_SGSN l3_mo;
2518 var PDU_L3_SGSN_MS l3_mt;
2519 var default di := activate(as_mm_identity());
2520
2521 var GSUP_IE auth_tuple;
2522 var template AuthenticationParameterAUTNTLV autn;
2523
2524 g_pars.vec := f_gen_auth_vec_3g();
2525 autn := {
2526 elementIdentifier := '28'O,
2527 lengthIndicator := lengthof(g_pars.vec.autn),
2528 autnValue := g_pars.vec.autn
2529 };
2530 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2531 g_pars.vec.sres,
2532 g_pars.vec.kc,
2533 g_pars.vec.ik,
2534 g_pars.vec.ck,
2535 g_pars.vec.autn,
2536 g_pars.vec.res));
2537 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2538 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2539 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2540
2541 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2542 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002543 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002544
2545 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002546 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002547
2548 /* wait for the GSUP resync request */
2549 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2550 g_pars.imsi,
2551 g_pars.vec.auts,
2552 g_pars.vec.rand));
2553
2554 /* generate new key material */
2555 g_pars.vec := f_gen_auth_vec_3g();
2556 autn := {
2557 elementIdentifier := '28'O,
2558 lengthIndicator := lengthof(g_pars.vec.autn),
2559 autnValue := g_pars.vec.autn
2560 };
2561
2562 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2563 g_pars.vec.sres,
2564 g_pars.vec.kc,
2565 g_pars.vec.ik,
2566 g_pars.vec.ck,
2567 g_pars.vec.autn,
2568 g_pars.vec.res));
2569 /* send new key material */
2570 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2571
2572 /* wait for the new Auth Request */
2573 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2574 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002575 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002576 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2577 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2578 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2579 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2580 valueField := substr(g_pars.vec.res, 0, 4)
2581 };
2582 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2583 elementIdentifier := '21'O,
2584 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2585 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2586 };
2587 l3_mo := valueof(auth_ciph_resp);
2588 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2589 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2590 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2591 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2592 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002593 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002594 deactivate(di);
2595
2596 /* Expect SGSN to perform LU with HLR */
2597 f_gmm_gsup_lu_isd();
2598
Harald Welte955aa942019-05-03 01:29:29 +02002599 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2600 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002601 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002602 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002603 setverdict(pass);
2604}
2605
2606testcase TC_attach_usim_resync() runs on test_CT {
2607 /* MS -> SGSN: Attach Request
2608 * MS <- SGSN: Identity Request IMSI
2609 * MS -> SGSN: Identity Response IMSI
2610 * MS <- SGSN: Identity Request IMEI
2611 * MS -> SGSN: Identity Response IMEI
2612 * HLR<- SGSN: SAI Request
2613 * HLR-> SGSN: SAI Response
2614 * MS <- SGSN: Auth Request
2615 * MS -> SGSN: Auth Failure (with AUTS)
2616 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2617 * HLR-> SGSN: SAI Response (new key material)
2618 * MS <- SGSN: Auth Request (new key material)
2619 * MS -> SGSN: Auth Response
2620 * MS <- SGSN: Attach Accept
2621 * MS -> SGSN: Attach Complete
2622 */
2623 var BSSGP_ConnHdlr vc_conn;
2624 f_init();
2625 f_sleep(1.0);
2626 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2627 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002628 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002629}
2630
Harald Weltea05b8072019-04-23 22:35:05 +02002631
2632/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2633private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2634 f_gmm_attach(false, false);
2635 f_sleep(1.0);
2636 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2637 /* try to detach to check if SGSN is still alive */
2638 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2639}
2640testcase TC_llc_null() runs on test_CT {
2641 var BSSGP_ConnHdlr vc_conn;
2642 f_init();
2643 f_sleep(1.0);
2644 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2645 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002646 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002647}
2648
Harald Welte645a1512019-04-23 23:18:23 +02002649/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2650private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2651 f_gmm_attach(false, false);
2652 f_sleep(1.0);
2653 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002654 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002655 setverdict(pass);
2656}
2657testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2658 var BSSGP_ConnHdlr vc_conn;
2659 f_init();
2660 f_sleep(1.0);
2661 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2662 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002663 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002664}
2665
2666/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2667private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2668 f_gmm_attach(false, false);
2669 f_sleep(1.0);
2670 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002671 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002672 setverdict(pass);
2673}
2674testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2675 var BSSGP_ConnHdlr vc_conn;
2676 f_init();
2677 f_sleep(1.0);
2678 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2679 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002680 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002681}
2682
Harald Welte2aaac1b2019-05-02 10:02:53 +02002683/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2684private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2685 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2686 var template (value) XID_Information xid;
2687 var template XID_Information xid_rx;
2688
2689 /* first perform regular attach */
2690 f_TC_attach(id);
2691 /* then activate PDP context */
2692 f_pdp_ctx_act(apars);
2693
2694 /* start MO XID */
2695 xid := { ts_XID_L3(''O) };
2696 xid_rx := { tr_XID_L3(''O) };
2697 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2698 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002699 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002700 [] as_xid(apars);
2701 }
2702 setverdict(pass);
2703}
2704testcase TC_xid_empty_l3() runs on test_CT {
2705 var BSSGP_ConnHdlr vc_conn;
2706 f_init();
2707 f_sleep(1.0);
2708 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2709 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002710 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002711}
2712
2713private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2714 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2715 var template (value) XID_Information xid;
2716 var template XID_Information xid_rx;
2717
2718 /* first perform regular attach */
2719 f_TC_attach(id);
2720 /* then activate PDP context */
2721 f_pdp_ctx_act(apars);
2722
2723 /* start MO XID */
2724 xid := { ts_XID_N201U(1234) };
2725 xid_rx := { tr_XID_N201U(1234) };
2726 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2727 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002728 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002729 [] as_xid(apars);
2730 }
2731 setverdict(pass);
2732}
2733testcase TC_xid_n201u() runs on test_CT {
2734 var BSSGP_ConnHdlr vc_conn;
2735 f_init();
2736 f_sleep(1.0);
2737 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2738 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002739 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002740}
2741
Alexander Couzens6bee0872019-05-11 01:48:50 +02002742private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2743 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2744
2745 /* first perform regular attach */
2746 f_TC_attach(id);
2747 /* then activate PDP context */
2748 f_pdp_ctx_act(apars);
2749 /* do a normal detach */
2750 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2751}
2752
2753testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2754 /* MS -> SGSN: Attach Request
2755 * MS <-> SGSN: [..]
2756 * MS -> SGSN: Attach Complete
2757 * MS -> SGSN: PDP Activate Request
2758 * MS <- SGSN: PDP Activate Accept
2759 * MS -> SGSN: GMM Detach Request
2760 * MS <- SGSN: GMM Detach Accept
2761 */
2762 var BSSGP_ConnHdlr vc_conn;
2763 f_init();
2764 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2765 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002766 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002767}
Harald Welte645a1512019-04-23 23:18:23 +02002768
Harald Welte5ac31492018-02-15 20:39:13 +01002769control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002770 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002771 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002772 execute( TC_attach_umts_aka_umts_res() );
2773 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002774 execute( TC_attach_auth_id_timeout() );
2775 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002776 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002777 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002778 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002779 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002780 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002781 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002782 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002783 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002784 execute( TC_attach_closed_add_vty(), 20.0 );
2785 execute( TC_attach_check_subscriber_list(), 20.0 );
2786 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002787 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002788 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2789 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2790 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2791 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002792 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002793 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002794 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002795 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002796 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002797 execute( TC_detach_unknown_nopoweroff() );
2798 execute( TC_detach_unknown_poweroff() );
2799 execute( TC_detach_nopoweroff() );
2800 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002801 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002802 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002803 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002804 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002805 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002806 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002807 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002808 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002809 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002810 execute( TC_attach_restart_ctr_echo() );
2811 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002812 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002813 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2814 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002815 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002816 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002817 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002818
Harald Welte2aaac1b2019-05-02 10:02:53 +02002819 execute( TC_xid_empty_l3() );
2820 execute( TC_xid_n201u() );
2821
Harald Weltea05b8072019-04-23 22:35:05 +02002822 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002823 execute( TC_llc_sabm_dm_llgmm() );
2824 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002825}
Harald Welte96a33b02018-02-04 10:36:22 +01002826
2827
2828
2829}