blob: c9309dd154ec1488d06c787b2ae810c405735044 [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,
Harald Welte5ac31492018-02-15 20:39:13 +0100172 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100173 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200174 float t_guard,
175 /* only in IuPS / RANAP case */
176 SCCP_PAR_Address sccp_addr_local,
177 SCCP_PAR_Address sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100178};
179
Alexander Couzens89508702018-07-31 04:16:10 +0200180private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200181 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200182 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
183
184 var RoutingAreaIdentificationV ret := {
185 mccDigit1 := mcc_mnc[0],
186 mccDigit2 := mcc_mnc[1],
187 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200188 mncDigit3 := mcc_mnc[3],
189 mncDigit1 := mcc_mnc[4],
190 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200191 lac := int2oct(cell_id.ra_id.lai.lac, 16),
192 rac := int2oct(cell_id.ra_id.rac, 8)
193 }
194 return ret;
195};
196
Alexander Couzens51114d12018-07-31 18:41:56 +0200197private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
198 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
199 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100200 /* connect lower end of BSSGP emulation with NS upper port */
201 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
202 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
203 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
204
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200205 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100206 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
207}
208
209private function f_init_gsup(charstring id) runs on test_CT {
210 id := id & "-GSUP";
211 var GsupOps ops := {
212 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
213 };
214
215 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
216 vc_GSUP := GSUP_Emulation_CT.create(id);
217
218 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
219 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
220 /* we use this hack to get events like ASP_IPA_EVENT_UP */
221 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
222
223 vc_GSUP.start(GSUP_Emulation.main(ops, id));
224 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
225
226 /* wait for incoming connection to GSUP port before proceeding */
227 timer T := 10.0;
228 T.start;
229 alt {
230 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
231 [] T.timeout {
232 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200233 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100234 }
235 }
236}
237
Harald Welteeded9ad2018-02-17 20:57:34 +0100238private function f_init_gtp(charstring id) runs on test_CT {
239 id := id & "-GTP";
240
241 var GtpEmulationCfg gtp_cfg := {
242 gtpc_bind_ip := mp_ggsn_ip,
243 gtpc_bind_port := GTP1C_PORT,
244 gtpu_bind_ip := mp_ggsn_ip,
245 gtpu_bind_port := GTP1U_PORT,
246 sgsn_role := false
247 };
248
249 vc_GTP := GTP_Emulation_CT.create(id);
250 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
251}
252
Harald Weltebd194722018-02-16 22:11:08 +0100253private function f_init_vty() runs on test_CT {
254 map(self:SGSNVTY, system:SGSNVTY);
255 f_vty_set_prompts(SGSNVTY);
256 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200257 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100258 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
259}
260
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200261private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
262 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200263 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200264 } else {
265 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
266 }
267}
268
Harald Weltebd194722018-02-16 22:11:08 +0100269
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200270/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
271function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200272 var integer i;
273
Harald Welte96a33b02018-02-04 10:36:22 +0100274 if (g_initialized == true) {
275 return;
276 }
277 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100278 g_gb[0].cfg := {
279 nsei := 96,
280 bvci := 196,
281 cell_id := {
282 ra_id := {
283 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100284 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100285 rac := 0
286 },
287 cell_id := 20960
288 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200289 sgsn_role := false,
290 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100291 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200292 g_gb[1].cfg := {
293 nsei := 97,
294 bvci := 210,
295 cell_id := {
296 ra_id := {
297 lai := {
298 mcc_mnc := mcc_mnc, lac := 13200},
299 rac := 0
300 },
301 cell_id := 20961
302 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200303 sgsn_role := false,
304 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200305 };
306 g_gb[2].cfg := {
307 nsei := 98,
308 bvci := 220,
309 cell_id := {
310 ra_id := {
311 lai := {
312 mcc_mnc := mcc_mnc, lac := 13300},
313 rac := 0
314 },
315 cell_id := 20962
316 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200317 sgsn_role := false,
318 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200319 };
Harald Welte96a33b02018-02-04 10:36:22 +0100320
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200321 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200322 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
323 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
324 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200325
326 for (i := 0; i < NUM_RNC; i := i+1) {
327 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
328 f_ran_adapter_start(g_ranap[i]);
329 }
Harald Welte5ac31492018-02-15 20:39:13 +0100330 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100331 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200332 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100333}
Harald Welte96a33b02018-02-04 10:36:22 +0100334
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200335function f_cleanup() runs on test_CT {
336 var integer i;
337 for (i := 0; i < NUM_RNC; i := i+1) {
338 f_ran_adapter_cleanup(g_ranap[i]);
339 }
340 self.stop;
341}
342
Harald Welte26fbb6e2019-04-14 17:32:46 +0200343private function RncUnitdataCallback(RANAP_PDU ranap)
344runs on RAN_Emulation_CT return template RANAP_PDU {
345 var template RANAP_PDU resp := omit;
346
347 log ("RANAP_RncUnitDataCallback");
348 /* answer all RESET with RESET ACK */
349 if (match(ranap, tr_RANAP_Reset)) {
350 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
351 var CN_DomainIndicator dom;
352 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
353 resp := ts_RANAP_ResetAck(dom);
354 }
355 return resp;
356}
357
358const RanOps RNC_RanOps := {
359 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
360 ranap_unitdata_cb := refers(RncUnitdataCallback),
361 ps_domain := true,
362 decode_dtap := true,
363 role_ms := true,
364 protocol := RAN_PROTOCOL_RANAP,
365 transport := RANAP_TRANSPORT_IuCS,
366 use_osmux := false,
367 sccp_addr_local := omit,
368 sccp_addr_peer := omit
369};
370
Harald Welte5ac31492018-02-15 20:39:13 +0100371type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
372
373/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200374function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100375 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100376runs on test_CT return BSSGP_ConnHdlr {
377 var BSSGP_ConnHdlr vc_conn;
378 var SGSN_ConnHdlrNetworkPars net_pars := {
379 expect_ptmsi := true,
380 expect_auth := true,
381 expect_ciph := false
382 };
383 var BSSGP_ConnHdlrPars pars := {
384 imei := f_gen_imei(imsi_suffix),
385 imsi := f_gen_imsi(imsi_suffix),
386 msisdn := f_gen_msisdn(imsi_suffix),
387 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100388 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100389 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100390 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100391 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200392 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Harald Welte5ac31492018-02-15 20:39:13 +0100393 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100394 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200395 t_guard := t_guard,
396 sccp_addr_local := g_ranap[0].sccp_addr_own,
397 sccp_addr_peer := g_ranap[0].sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100398 };
399
400 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200401 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
402 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
403 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
404 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
405 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
406 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100407
Harald Welte26fbb6e2019-04-14 17:32:46 +0200408 /* FIXME: support multiple RNCs */
409 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
410 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
411
Harald Welte5ac31492018-02-15 20:39:13 +0100412 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
413 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
414
Harald Welteeded9ad2018-02-17 20:57:34 +0100415 connect(vc_conn:GTP, vc_GTP:CLIENT);
416 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
417
Harald Welte5ac31492018-02-15 20:39:13 +0100418 vc_conn.start(f_handler_init(fn, id, pars));
419 return vc_conn;
420}
421
Harald Welte62e29582018-02-16 21:17:11 +0100422private altstep as_Tguard() runs on BSSGP_ConnHdlr {
423 [] g_Tguard.timeout {
424 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200425 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100426 }
427}
428
Harald Welte5ac31492018-02-15 20:39:13 +0100429/* first function called in every ConnHdlr */
430private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
431runs on BSSGP_ConnHdlr {
432 /* do some common stuff like setting up g_pars */
433 g_pars := pars;
434
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200435 llc := f_llc_create(false);
436
Harald Welte5ac31492018-02-15 20:39:13 +0100437 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200438 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100439 /* tell GSUP dispatcher to send this IMSI to us */
440 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100441 /* tell GTP dispatcher to send this IMSI to us */
442 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100443
Harald Welte62e29582018-02-16 21:17:11 +0100444 g_Tguard.start(pars.t_guard);
445 activate(as_Tguard());
446
Harald Welte5ac31492018-02-15 20:39:13 +0100447 /* call the user-supplied test case function */
448 fn.apply(id);
449 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100450}
451
452/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100453 * Detach without Attach
454 * SM procedures without attach / RAU
455 * ATTACH / RAU
456 ** with / without authentication
457 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100458 * re-transmissions of LLC frames
459 * PDP Context activation
460 ** with different GGSN config in SGSN VTY
461 ** with different PDP context type (v4/v6/v46)
462 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100463 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100464 */
465
466testcase TC_wait_ns_up() runs on test_CT {
467 f_init();
468 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200469 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100470}
471
Harald Weltea05b8072019-04-23 22:35:05 +0200472function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
473 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
474 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
475}
476
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200477function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
478 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
479 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
480 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200481 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200482}
483
Harald Welteca362462019-05-02 20:11:21 +0200484altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100485 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welte955aa942019-05-03 01:29:29 +0200486 [] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100487 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200488 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100489 repeat;
490 }
Harald Welte955aa942019-05-03 01:29:29 +0200491 [] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100492 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200493 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100494 repeat;
495 }
496}
Harald Welte96a33b02018-02-04 10:36:22 +0100497
Harald Welteca362462019-05-02 20:11:21 +0200498/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
499function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
500runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Harald Welteca362462019-05-02 20:11:21 +0200501 var PDU_L3_SGSN_MS l3_mt;
502 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200503 [] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
Harald Welteca362462019-05-02 20:11:21 +0200504 }
505 return l3_mt;
506}
507
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200508/* perform GMM authentication (if expected).
509 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
510 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200511function 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 +0100512 var PDU_L3_MS_SGSN l3_mo;
513 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200514 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100515 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200516 var GSUP_IE auth_tuple;
517 var template AuthenticationParameterAUTNTLV autn;
518
519 if (umts_aka_challenge) {
520 g_pars.vec := f_gen_auth_vec_3g();
521 autn := {
522 elementIdentifier := '28'O,
523 lengthIndicator := lengthof(g_pars.vec.autn),
524 autnValue := g_pars.vec.autn
525 };
526
527 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
528 g_pars.vec.sres,
529 g_pars.vec.kc,
530 g_pars.vec.ik,
531 g_pars.vec.ck,
532 g_pars.vec.autn,
533 g_pars.vec.res));
534 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
535 } else {
536 g_pars.vec := f_gen_auth_vec_2g();
537 autn := omit;
538 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
539 g_pars.vec.sres,
540 g_pars.vec.kc));
541 log("GSUP sends only 2G auth tuple", auth_tuple);
542 }
Harald Welteca362462019-05-02 20:11:21 +0200543
Harald Welte5ac31492018-02-15 20:39:13 +0100544 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
545 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200546
547 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
548 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200549 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100550 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200551 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
552
553 if (umts_aka_challenge and not force_gsm_sres) {
554 /* set UMTS response instead */
555 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
556 valueField := substr(g_pars.vec.res, 0, 4)
557 };
558 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
559 elementIdentifier := '21'O,
560 lengthIndicator := lengthof(g_pars.vec.res) - 4,
561 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
562 };
563 }
564
565 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100566 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
567 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
568 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
569 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
570 }
Harald Welteca362462019-05-02 20:11:21 +0200571 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100572 } else {
573 /* wait for identity procedure */
574 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100575 }
Harald Welte76dee092018-02-16 22:12:59 +0100576
Harald Welte5ac31492018-02-15 20:39:13 +0100577 deactivate(di);
578}
579
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200580function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100581 g_pars.p_tmsi := p_tmsi;
582 /* update TLLI */
583 g_pars.tlli_old := g_pars.tlli;
584 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200585 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100586}
587
Harald Welte04683d02018-02-16 22:43:45 +0100588function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
589 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100590 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200591 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100592 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200593 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200594 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100595 }
Harald Welte04683d02018-02-16 22:43:45 +0100596 g_pars.ra := aa.routingAreaIdentification;
597 if (ispresent(aa.allocatedPTMSI)) {
598 if (not g_pars.net.expect_ptmsi) {
599 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200600 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100601 }
Harald Weltef70997d2018-02-17 10:11:19 +0100602 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100603 }
604 if (ispresent(aa.msIdentity)) {
605 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200606 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100607 }
608 /* P-TMSI.sig */
609 if (ispresent(aa.ptmsiSignature)) {
610 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
611 }
612 /* updateTimer */
613 // aa.readyTimer
614 /* T3302, T3319, T3323, T3312_ext, T3324 */
615}
616
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200617function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100618 /* mandatory IE */
619 g_pars.ra := ra.routingAreaId;
620 if (ispresent(ra.allocatedPTMSI)) {
621 if (not g_pars.net.expect_ptmsi) {
622 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200623 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100624 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200625 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100626 }
627 if (ispresent(ra.msIdentity)) {
628 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200629 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100630 }
631 /* P-TMSI.sig */
632 if (ispresent(ra.ptmsiSignature)) {
633 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
634 }
635 /* updateTimer */
636 // aa.readyTimer
637 /* T3302, T3319, T3323, T3312_ext, T3324 */
638}
639
640
Harald Welte5a4fa042018-02-16 20:59:21 +0100641function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
642 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
643}
644
Harald Welte23178c52018-02-17 09:36:33 +0100645/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100646private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100647 if (ispresent(g_pars.p_tmsi)) {
648 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
649 } else {
650 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
651 }
652}
653
Harald Welte311ec272018-02-17 09:40:03 +0100654private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100655 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100656 /* Expect MSC to perform LU with HLR */
657 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100658 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
659 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
660 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100661 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
662 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
663}
664
Harald Welteca362462019-05-02 20:11:21 +0200665friend 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 +0100666 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200667 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 +0200668 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100669
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200670 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
671 * 3G auth vectors */
672 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
673 /* The thing is, if the solSACapability is 'omit', then the
674 * revisionLevelIndicatior is at the wrong place! */
675 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
676
Harald Welteca362462019-05-02 20:11:21 +0200677 f_send_l3_gmm_llc(attach_req, gb_idx);
678 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200679 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100680 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100681
Harald Welteca362462019-05-02 20:11:21 +0200682 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
683 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
684
Harald Welte04683d02018-02-16 22:43:45 +0100685 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200686 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200687}
688
689private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
690 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100691 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100692}
693
694testcase TC_attach() runs on test_CT {
695 var BSSGP_ConnHdlr vc_conn;
696 f_init();
697 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200698 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100699 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200700 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100701}
702
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100703testcase TC_attach_mnc3() runs on test_CT {
704 var BSSGP_ConnHdlr vc_conn;
705 f_init('023042'H);
706 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200707 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100708 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200709 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100710}
711
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200712private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
713 f_gmm_attach(true, false);
714 setverdict(pass);
715}
716testcase TC_attach_umts_aka_umts_res() runs on test_CT {
717 var BSSGP_ConnHdlr vc_conn;
718 f_init();
719 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200720 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200721 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200722 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200723}
724
725private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
726 f_gmm_attach(true, true);
727 setverdict(pass);
728}
729testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
730 var BSSGP_ConnHdlr vc_conn;
731 f_init();
732 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200733 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200734 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200735 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200736}
737
Harald Welte5b7c8122018-02-16 21:48:17 +0100738/* MS never responds to ID REQ, expect ATTACH REJECT */
739private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100740 var RoutingAreaIdentificationV old_ra := f_random_RAI();
741
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200742 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100743 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200744 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100745 /* don't send ID Response */
746 repeat;
747 }
Harald Welte955aa942019-05-03 01:29:29 +0200748 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100749 setverdict(pass);
750 }
Harald Welte955aa942019-05-03 01:29:29 +0200751 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100752 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200753 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100754 }
755 }
756}
757testcase TC_attach_auth_id_timeout() runs on test_CT {
758 var BSSGP_ConnHdlr vc_conn;
759 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200760 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 +0100761 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200762 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100763}
764
765/* HLR never responds to SAI REQ, expect ATTACH REJECT */
766private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100767 var RoutingAreaIdentificationV old_ra := f_random_RAI();
768
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200769 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100770 alt {
771 [] as_mm_identity();
772 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
773 }
774 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200775 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100776 setverdict(pass);
777}
778testcase TC_attach_auth_sai_timeout() runs on test_CT {
779 var BSSGP_ConnHdlr vc_conn;
780 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200781 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100782 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200783 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100784}
785
Harald Weltefe253882018-02-17 09:25:00 +0100786/* HLR rejects SAI, expect ATTACH REJECT */
787private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100788 var RoutingAreaIdentificationV old_ra := f_random_RAI();
789
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200790 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100791 alt {
792 [] as_mm_identity();
793 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
794 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
795 }
796 }
Harald Welte955aa942019-05-03 01:29:29 +0200797 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100798 setverdict(pass);
799}
800testcase TC_attach_auth_sai_reject() runs on test_CT {
801 var BSSGP_ConnHdlr vc_conn;
802 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200803 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100804 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200805 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100806}
807
Harald Welte5b7c8122018-02-16 21:48:17 +0100808/* HLR never responds to UL REQ, expect ATTACH REJECT */
809private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200810 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100811 var RoutingAreaIdentificationV old_ra := f_random_RAI();
812
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200813 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100814 f_gmm_auth();
815 /* Expect MSC to perform LU with HLR */
816 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
817 /* Never follow-up with ISD_REQ or UL_RES */
818 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200819 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100820 setverdict(pass);
821 }
Harald Welte955aa942019-05-03 01:29:29 +0200822 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
823 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100824 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200825 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100826 }
827 }
828}
829testcase TC_attach_gsup_lu_timeout() runs on test_CT {
830 var BSSGP_ConnHdlr vc_conn;
831 f_init();
832 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200833 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100834 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200835 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100836}
837
Harald Welteb7c14e92018-02-17 09:29:16 +0100838/* HLR rejects UL REQ, expect ATTACH REJECT */
839private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200840 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100841 var RoutingAreaIdentificationV old_ra := f_random_RAI();
842
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200843 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100844 f_gmm_auth();
845 /* Expect MSC to perform LU with HLR */
846 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
847 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
848 }
849 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200850 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100851 setverdict(pass);
852 }
Harald Welte955aa942019-05-03 01:29:29 +0200853 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
854 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100855 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200856 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100857 }
858 }
859}
860testcase TC_attach_gsup_lu_reject() runs on test_CT {
861 var BSSGP_ConnHdlr vc_conn;
862 f_init();
863 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200864 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100865 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200866 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100867}
868
869
Harald Welte3823e2e2018-02-16 21:53:48 +0100870/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
871private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200872 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100873 var RoutingAreaIdentificationV old_ra := f_random_RAI();
874
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200875 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100876 f_gmm_auth();
877 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100878 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100879
Harald Welte955aa942019-05-03 01:29:29 +0200880 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
881 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100882 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200883 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100884 setverdict(pass);
885}
Harald Welte3823e2e2018-02-16 21:53:48 +0100886testcase TC_attach_combined() runs on test_CT {
887 var BSSGP_ConnHdlr vc_conn;
888 f_init();
889 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200890 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100891 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200892 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +0100893}
894
Harald Welte76dee092018-02-16 22:12:59 +0100895/* Attempt of GPRS ATTACH in 'accept all' mode */
896private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200897 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100898 var RoutingAreaIdentificationV old_ra := f_random_RAI();
899
900 g_pars.net.expect_auth := false;
901
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200902 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100903 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +0200904 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
905 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100906 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200907 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100908 setverdict(pass);
909}
910testcase TC_attach_accept_all() runs on test_CT {
911 var BSSGP_ConnHdlr vc_conn;
912 f_init();
913 f_sleep(1.0);
914 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200915 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100916 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200917 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +0100918}
Harald Welte5b7c8122018-02-16 21:48:17 +0100919
Harald Welteb2124b22018-02-16 22:26:56 +0100920/* Attempt of GPRS ATTACH in 'accept all' mode */
921private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100922 var RoutingAreaIdentificationV old_ra := f_random_RAI();
923
924 /* Simulate a foreign IMSI */
925 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200926 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100927
928 g_pars.net.expect_auth := false;
929
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200930 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100931 alt {
932 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +0200933 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100934 setverdict(pass);
935 }
Harald Welte955aa942019-05-03 01:29:29 +0200936 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100937 setverdict(pass);
938 }
Harald Welte955aa942019-05-03 01:29:29 +0200939 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200940 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200941 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200942 }
Harald Welteb2124b22018-02-16 22:26:56 +0100943 }
944}
945testcase TC_attach_closed() runs on test_CT {
946 var BSSGP_ConnHdlr vc_conn;
947 f_init();
948 f_sleep(1.0);
949 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
950 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200951 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100952 vc_conn.done;
953 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200954 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100955 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200956 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +0100957}
958
Harald Welte04683d02018-02-16 22:43:45 +0100959/* Routing Area Update from Unknown TLLI -> REJECT */
960private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100961 var RoutingAreaIdentificationV old_ra := f_random_RAI();
962
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200963 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100964 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200965 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +0100966 setverdict(pass);
967 }
968 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200969 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100970 }
971}
972testcase TC_rau_unknown() runs on test_CT {
973 var BSSGP_ConnHdlr vc_conn;
974 f_init();
975 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200976 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100977 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200978 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +0100979}
980
Harald Welte91636de2018-02-17 10:16:14 +0100981private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100982 /* first perform regular attach */
983 f_TC_attach(id);
984
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200985 f_routing_area_update(g_pars.ra);
986
Harald Welte91636de2018-02-17 10:16:14 +0100987}
988testcase TC_attach_rau() runs on test_CT {
989 var BSSGP_ConnHdlr vc_conn;
990 f_init();
991 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200992 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100993 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200994 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +0100995}
Harald Welte04683d02018-02-16 22:43:45 +0100996
Harald Welte6abb9fe2018-02-17 15:24:48 +0100997/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200998function 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 +0200999 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001000 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001001 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001002 if (expect_purge) {
1003 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1004 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1005 }
1006 T.start;
1007 alt {
1008 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1009 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001010 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001011 }
Harald Welte955aa942019-05-03 01:29:29 +02001012 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001013 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001014 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001015 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001016 /* TODO: check if any PDP contexts are deactivated on network side? */
1017 }
1018 [power_off] T.timeout {
1019 setverdict(pass);
1020 }
Harald Welte955aa942019-05-03 01:29:29 +02001021 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001022 g_pars.ra := omit;
1023 setverdict(pass);
1024 /* TODO: check if any PDP contexts are deactivated on network side? */
1025 }
Harald Welte955aa942019-05-03 01:29:29 +02001026 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001027 if (power_off) {
1028 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1029 } else {
1030 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1031 }
1032 mtc.stop;
1033 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001034 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001035 }
1036}
1037
1038/* IMSI DETACH (non-power-off) for unknown TLLI */
1039private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1040 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1041}
1042testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1043 var BSSGP_ConnHdlr vc_conn;
1044 f_init();
1045 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001046 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001047 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001048 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001049}
1050
1051/* IMSI DETACH (power-off) for unknown TLLI */
1052private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1053 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1054}
1055testcase TC_detach_unknown_poweroff() runs on test_CT {
1056 var BSSGP_ConnHdlr vc_conn;
1057 f_init();
1058 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001059 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001060 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001061 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001062}
1063
1064/* IMSI DETACH (non-power-off) for known TLLI */
1065private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1066 /* first perform regular attach */
1067 f_TC_attach(id);
1068
1069 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1070}
1071testcase TC_detach_nopoweroff() runs on test_CT {
1072 var BSSGP_ConnHdlr vc_conn;
1073 f_init();
1074 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001075 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001076 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001077 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001078}
1079
1080/* IMSI DETACH (power-off) for known TLLI */
1081private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1082 /* first perform regular attach */
1083 f_TC_attach(id);
1084
1085 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1086}
1087testcase TC_detach_poweroff() runs on test_CT {
1088 var BSSGP_ConnHdlr vc_conn;
1089 f_init();
1090 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001091 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001092 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001093 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001094}
1095
Harald Welteeded9ad2018-02-17 20:57:34 +01001096type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001097 BIT3 tid, /* L3 Transaction ID */
1098 BIT4 nsapi, /* SNDCP NSAPI */
1099 BIT4 sapi, /* LLC SAPI */
1100 QoSV qos, /* QoS parameters */
1101 PDPAddressV addr, /* IP address */
1102 octetstring apn optional, /* APN name */
1103 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1104 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001105 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001106 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001107
Harald Welte822f9102018-02-18 20:39:06 +01001108 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1109 OCT4 ggsn_tei_u, /* GGSN TEI User */
1110 octetstring ggsn_ip_c, /* GGSN IP Control */
1111 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001112 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001113
Harald Welte822f9102018-02-18 20:39:06 +01001114 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1115 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1116 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1117 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001118};
1119
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001120
1121private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1122 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1123 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1124 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1125 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1126 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1127 f_gtp_register_teid(apars.ggsn_tei_c);
1128 f_gtp_register_teid(apars.ggsn_tei_u);
1129}
1130
Harald Weltef7191672019-05-02 20:37:23 +02001131function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1132runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001133 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1134 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001135 var template Recovery_gtpc recovery := omit;
1136
1137 if (send_recovery) {
1138 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1139 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001140
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001141 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001142 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001143 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1144 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1145 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1146 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1147 apars.sgsn_tei_c, apars.gtp_resp_cause,
1148 apars.ggsn_tei_c, apars.ggsn_tei_u,
1149 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001150 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1151 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001152 }
1153 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001154 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001155 setverdict(pass);
1156 }
Harald Welte955aa942019-05-03 01:29:29 +02001157 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001158 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001159 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001160 }
Harald Welte955aa942019-05-03 01:29:29 +02001161 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001162 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001163 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001164 }
Harald Welte955aa942019-05-03 01:29:29 +02001165 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001166 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1167 mtc.stop;
1168 }
Harald Welte955aa942019-05-03 01:29:29 +02001169 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001170 setverdict(pass);
1171 }
Harald Weltef7191672019-05-02 20:37:23 +02001172 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001173 }
1174}
1175
Harald Weltef7191672019-05-02 20:37:23 +02001176function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1177runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001178 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1179 var Gtp1cUnitdata g_ud;
1180
Harald Weltef7191672019-05-02 20:37:23 +02001181 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001182 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1183 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001184 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001185 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1186 }
1187 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001188 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001189 setverdict(pass);
1190 }
Harald Weltef7191672019-05-02 20:37:23 +02001191 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001192 }
1193}
1194
Harald Weltef7191672019-05-02 20:37:23 +02001195function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1196runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001197 var Gtp1cUnitdata g_ud;
1198 var integer seq_nr := 23;
1199 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1200
Harald Weltef7191672019-05-02 20:37:23 +02001201 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001202 if (error_ind) {
1203 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1204 } else {
1205 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1206 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001207
1208 timer T := 5.0;
1209 T.start;
1210
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001211 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001212 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Harald Weltef7191672019-05-02 20:37:23 +02001213 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001214 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001215 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1216 repeat;
1217 }
1218 [] T.timeout {
1219 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1220 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001221 }
1222}
1223
Harald Welte6f203162018-02-18 22:04:55 +01001224
Harald Welteeded9ad2018-02-17 20:57:34 +01001225/* Table 10.5.156/3GPP TS 24.008 */
1226template (value) QoSV t_QosDefault := {
1227 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1228 delayClass := '100'B, /* best effort */
1229 spare1 := '00'B,
1230 precedenceClass := '010'B, /* normal */
1231 spare2 := '0'B,
1232 peakThroughput := '0000'B, /* subscribed */
1233 meanThroughput := '00000'B, /* subscribed */
1234 spare3 := '000'B,
1235 deliverErroneusSDU := omit,
1236 deliveryOrder := omit,
1237 trafficClass := omit,
1238 maxSDUSize := omit,
1239 maxBitrateUplink := omit,
1240 maxBitrateDownlink := omit,
1241 sduErrorRatio := omit,
1242 residualBER := omit,
1243 trafficHandlingPriority := omit,
1244 transferDelay := omit,
1245 guaranteedBitRateUplink := omit,
1246 guaranteedBitRateDownlink := omit,
1247 sourceStatisticsDescriptor := omit,
1248 signallingIndication := omit,
1249 spare4 := omit,
1250 maxBitrateDownlinkExt := omit,
1251 guaranteedBitRateDownlinkExt := omit,
1252 maxBitrateUplinkExt := omit,
1253 guaranteedBitRateUplinkExt := omit,
1254 maxBitrateDownlinkExt2 := omit,
1255 guaranteedBitRateDownlinkExt2 := omit,
1256 maxBitrateUplinkExt2 := omit,
1257 guaranteedBitRateUplinkExt2 := omit
1258}
1259
1260/* 10.5.6.4 / 3GPP TS 24.008 */
1261template (value) PDPAddressV t_AddrIPv4dyn := {
1262 pdpTypeOrg := '0001'B, /* IETF */
1263 spare := '0000'B,
1264 pdpTypeNum := '21'O, /* IPv4 */
1265 addressInfo := omit
1266}
1267template (value) PDPAddressV t_AddrIPv6dyn := {
1268 pdpTypeOrg := '0001'B, /* IETF */
1269 spare := '0000'B,
1270 pdpTypeNum := '53'O, /* IPv6 */
1271 addressInfo := omit
1272}
1273
Harald Welte37692d82018-02-18 15:21:34 +01001274template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001275 tid := '000'B,
1276 nsapi := '0101'B, /* < 5 are reserved */
1277 sapi := '0011'B, /* 3/5/9/11 */
1278 qos := t_QosDefault,
1279 addr := t_AddrIPv4dyn,
1280 apn := omit,
1281 pco := omit,
1282 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001283 gtp_resp_cause := int2oct(128, 1),
1284 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001285
1286 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001287 ggsn_tei_c := f_rnd_octstring(4),
1288 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001289 ggsn_ip_c := f_inet_addr(ggsn_ip),
1290 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001291 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001292
Harald Welteeded9ad2018-02-17 20:57:34 +01001293 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001294 sgsn_tei_u := omit,
1295 sgsn_ip_c := omit,
1296 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001297}
1298
Harald Welte37692d82018-02-18 15:21:34 +01001299template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1300 connId := 1,
1301 remName := f_inet_ntoa(ip),
1302 remPort := GTP1U_PORT
1303}
1304
1305template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1306 connId := 1,
1307 remName := f_inet_ntoa(ip),
1308 remPort := GTP1C_PORT
1309}
1310
1311private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1312 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1313 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1314}
1315
Harald Weltef7191672019-05-02 20:37:23 +02001316private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001317 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001318 repeat;
1319 }
1320}
1321
1322template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1323 pDU_SN_UNITDATA := {
1324 nsapi := nsapi,
1325 moreBit := ?,
1326 snPduType := '1'B,
1327 firstSegmentIndicator := ?,
1328 spareBit := ?,
1329 pcomp := ?,
1330 dcomp := ?,
1331 npduNumber := ?,
1332 segmentNumber := ?,
1333 npduNumberContinued := ?,
1334 dataSegmentSnUnitdataPdu := payload
1335 }
1336}
1337
1338/* simple case: single segment, no compression */
1339template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1340 pDU_SN_UNITDATA := {
1341 nsapi := nsapi,
1342 moreBit := '0'B,
1343 snPduType := '1'B,
1344 firstSegmentIndicator := '1'B,
1345 spareBit := '0'B,
1346 pcomp := '0000'B,
1347 dcomp := '0000'B,
1348 npduNumber := '0000'B,
1349 segmentNumber := '0000'B,
1350 npduNumberContinued := '00'O,
1351 dataSegmentSnUnitdataPdu := payload
1352 }
1353}
1354
1355/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001356private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1357runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001358 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1359 f_gtpu_send(apars, payload);
1360 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1361 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001362 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001363 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1364 [] BSSGP[gb_idx].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001365 }
1366}
1367
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001368/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001369private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1370runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001371 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1372 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1373 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001374 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001375 /* Expect PDU via GTP from SGSN on simulated GGSN */
1376 alt {
1377 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1378 }
1379}
1380
Harald Welteeded9ad2018-02-17 20:57:34 +01001381private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001382 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001383
1384 /* first perform regular attach */
1385 f_TC_attach(id);
1386
1387 f_pdp_ctx_act(apars);
1388}
1389testcase TC_attach_pdp_act() runs on test_CT {
1390 var BSSGP_ConnHdlr vc_conn;
1391 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001392 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001393 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001394 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001395}
Harald Welteb2124b22018-02-16 22:26:56 +01001396
Harald Welte835b15f2018-02-18 14:39:11 +01001397/* PDP Context activation for not-attached subscriber; expect fail */
1398private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001399 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001400 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001401 apars.apn, apars.pco));
1402 alt {
1403 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001404 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001405 setverdict(pass);
1406 }
1407 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1408 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001409 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001410 }
Harald Welte955aa942019-05-03 01:29:29 +02001411 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001412 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001413 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001414 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001415 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001416 }
1417}
1418testcase TC_pdp_act_unattached() runs on test_CT {
1419 var BSSGP_ConnHdlr vc_conn;
1420 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001421 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001422 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001423 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001424}
1425
Harald Welte37692d82018-02-18 15:21:34 +01001426/* ATTACH + PDP CTX ACT + user plane traffic */
1427private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1428 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1429
1430 /* first perform regular attach */
1431 f_TC_attach(id);
1432 /* then activate PDP context */
1433 f_pdp_ctx_act(apars);
1434 /* then transceive a downlink PDU */
1435 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1436 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1437}
1438testcase TC_attach_pdp_act_user() runs on test_CT {
1439 var BSSGP_ConnHdlr vc_conn;
1440 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001441 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001442 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001443 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001444}
1445
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001446/* ATTACH + PDP CTX ACT; reject from GGSN */
1447private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1448 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1449
1450 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1451 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1452
1453 /* first perform regular attach */
1454 f_TC_attach(id);
1455 /* then activate PDP context */
1456 f_pdp_ctx_act(apars);
1457}
1458testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1459 var BSSGP_ConnHdlr vc_conn;
1460 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001461 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001462 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001463 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001464}
Harald Welte835b15f2018-02-18 14:39:11 +01001465
Harald Welte6f203162018-02-18 22:04:55 +01001466/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1467private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1468 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1469
1470 /* first perform regular attach */
1471 f_TC_attach(id);
1472 /* then activate PDP context */
1473 f_pdp_ctx_act(apars);
1474 /* then transceive a downlink PDU */
1475 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1476 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1477
1478 f_pdp_ctx_deact_mo(apars, '00'O);
1479}
1480testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1481 var BSSGP_ConnHdlr vc_conn;
1482 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001483 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 +01001484 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001485 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001486}
1487
Harald Welte57b9b7f2018-02-18 22:28:13 +01001488/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1489private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1490 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1491
1492 /* first perform regular attach */
1493 f_TC_attach(id);
1494 /* then activate PDP context */
1495 f_pdp_ctx_act(apars);
1496 /* then transceive a downlink PDU */
1497 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1498 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1499
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001500 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001501}
1502testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1503 var BSSGP_ConnHdlr vc_conn;
1504 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001505 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mt), testcasename(), g_gb, 22);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001506 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001507 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001508}
1509
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001510/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1511private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1512 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1513 var Gtp1cUnitdata g_ud;
1514 var integer i;
1515 var OCT1 cause_regular_deact := '24'O;
1516
1517 /* first perform regular attach + PDP context act */
1518 f_TC_attach(id);
1519 f_pdp_ctx_act(apars);
1520
1521 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1522 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1523
1524 for (i := 0; i < 2; i := i+1) {
1525 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1526 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1527 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1528 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1529 }
1530 }
1531
1532 alt {
1533 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1534 setverdict(pass);
1535 }
1536 [] as_xid(apars, 0);
1537 }
1538
1539 /* Make sure second DeactPdpAccept is sent: */
1540 timer T := 2.0;
1541 T.start;
1542 alt {
1543 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1544 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1545 }
1546 [] T.timeout {
1547 setverdict(pass);
1548 }
1549 }
1550
1551 setverdict(pass);
1552}
1553testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1554 var BSSGP_ConnHdlr vc_conn;
1555 f_init();
1556 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1557 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001558 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001559}
1560
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001561/* ATTACH + ATTACH (2nd) */
1562private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1563 g_pars.t_guard := 5.0;
1564
1565 /* first perform regular attach */
1566 f_TC_attach(id);
1567
1568 /* second to perform regular attach */
1569 f_TC_attach(id);
1570}
1571
1572
1573testcase TC_attach_second_attempt() runs on test_CT {
1574 var BSSGP_ConnHdlr vc_conn;
1575 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001576 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001577 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001578 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001579}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001580
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001581private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1582 var Gtp1cUnitdata g_ud;
1583 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1584 var integer seq_nr;
1585
1586 /* first perform regular attach */
1587 f_TC_attach(id);
1588 /* then activate PDP context */
1589 f_pdp_ctx_act(apars);
1590
1591 /* Wait to receive first echo request and send initial Restart counter */
1592 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1593 BSSGP[0].clear;
1594 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1595 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1596 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1597 }
1598
1599 /* At some point next echo request not answered will timeout and SGSN
1600 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1601 timer T := 3.0 * 6.0 + 16.0;
1602 T.start;
1603 alt {
1604 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1605 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1606 setverdict(pass);
1607 }
1608 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1609 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1610 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1611 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1612 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1613 repeat;
1614 }
1615 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1616 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1617 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1618 repeat;
1619 }
1620 [] T.timeout {
1621 setverdict(fail, "BSSGP DeactPdpReq not received");
1622 mtc.stop;
1623 }
1624 [] as_xid(apars);
1625 }
1626 T.stop
1627
1628 setverdict(pass);
1629}
1630/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1631testcase TC_attach_echo_timeout() runs on test_CT {
1632 var BSSGP_ConnHdlr vc_conn;
1633 g_use_echo := true;
1634 f_init();
1635 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1636 vc_conn.done;
1637 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001638 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001639}
1640
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001641private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001642 var Gtp1cUnitdata g_ud;
1643 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1644
1645 /* first perform regular attach */
1646 f_TC_attach(id);
1647 /* Activate a pdp context against the GGSN */
1648 f_pdp_ctx_act(apars);
1649 /* Wait to receive first echo request and send initial Restart counter */
1650 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1651 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1652 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1653 }
1654 /* Wait to receive second echo request and send incremented Restart
1655 counter. This will fake a restarted GGSN, and pdp ctx allocated
1656 should be released by SGSN */
1657 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1658 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1659 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1660 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1661 }
1662 var OCT1 cause_network_failure := int2oct(38, 1)
1663 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001664 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001665 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001666 setverdict(pass);
1667 }
1668 [] as_xid(apars);
1669 }
1670 setverdict(pass);
1671}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001672/* ATTACH + trigger Recovery procedure through EchoResp */
1673testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001674 var BSSGP_ConnHdlr vc_conn;
1675 g_use_echo := true
1676 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001677 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 +02001678 vc_conn.done;
1679 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001680 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001681}
1682
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001683private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1684 var Gtp1cUnitdata g_ud;
1685 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1686 var integer seq_nr := 23;
1687 var GtpPeer peer;
1688 /* first perform regular attach */
1689 f_TC_attach(id);
1690
1691 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1692 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1693 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1694 f_pdp_ctx_act(apars, true);
1695
1696 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1697/* received. */
1698 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1699
1700 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1701 would be great to have an active pdp context here before triggering
1702 Recovery, and making sure the the DEACT request is sent by the SGSN.
1703 */
1704
1705 /* Activate a pdp context against the GGSN, send incremented Recovery
1706 IE. This should trigger the recovery path, but still this specific
1707 CTX activation should work. */
1708 apars.exp_rej_cause := omit; /* default value for tests */
1709 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1710 f_pdp_ctx_act(apars, true);
1711
1712 setverdict(pass);
1713}
1714/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1715testcase TC_attach_restart_ctr_create() runs on test_CT {
1716 var BSSGP_ConnHdlr vc_conn;
1717 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001718 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 +02001719 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001720 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001721}
1722
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001723/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1724private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1725 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1726 var integer seq_nr := 23;
1727 var GtpPeer peer;
1728 var integer i;
1729
1730 /* first perform regular attach */
1731 f_TC_attach(id);
1732 /* then activate PDP context */
1733 f_pdp_ctx_act(apars);
1734
Alexander Couzens0e510e62018-07-28 23:06:00 +02001735 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001736 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1737 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1738
1739 for (i := 0; i < 5; i := i+1) {
1740 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001741 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001742 [] as_xid(apars);
1743 }
1744 }
1745
1746 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1747
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001748 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001749 setverdict(pass);
1750}
1751testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1752 var BSSGP_ConnHdlr vc_conn;
1753 f_init();
1754 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001755 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 +02001756 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001757 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001758}
1759
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001760/* ATTACH + PDP CTX ACT dropped + retrans */
1761private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1762 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1763 var Gtp1cUnitdata g_ud_first, g_ud_second;
1764 /* first perform regular attach */
1765 f_TC_attach(id);
1766
1767 /* then activate PDP context on the Gb side */
1768 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1769 apars.apn, apars.pco), 0);
1770
1771 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1772 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1773 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1774 if (g_ud_first != g_ud_second) {
1775 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1776 mtc.stop;
1777 }
1778 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1779 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1780 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1781 apars.sgsn_tei_c, apars.gtp_resp_cause,
1782 apars.ggsn_tei_c, apars.ggsn_tei_u,
1783 apars.nsapi,
1784 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1785 omit, omit));
1786 }
Harald Welte955aa942019-05-03 01:29:29 +02001787 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001788
1789 /* Now the same with Deact */
1790 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1791 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1792 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1793 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1794 if (g_ud_first != g_ud_second) {
1795 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1796 mtc.stop;
1797 }
1798 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1799 BSSGP[0].clear;
1800 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1801 }
1802 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001803 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001804 setverdict(pass);
1805 }
1806 [] as_xid(apars, 0);
1807 }
1808
1809 setverdict(pass);
1810}
1811testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1812 var BSSGP_ConnHdlr vc_conn;
1813 f_init();
1814 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1815 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001816 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001817}
1818
1819/* Test that SGSN GTP response retransmit queue works fine */
1820private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1821 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1822 var integer seq_nr := 23;
1823 var Gtp1cUnitdata g_ud_first, g_ud_second;
1824 var template Gtp1cUnitdata g_delete_req;
1825 /* first perform regular attach + PDP context act */
1826 f_TC_attach(id);
1827 f_pdp_ctx_act(apars);
1828
1829 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1830 BSSGP[0].clear;
1831 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1832 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1833 GTP.send(g_delete_req);
1834 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001835 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001836 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1837 }
1838 [] as_xid(apars, 0);
1839 }
1840 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1841 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1842 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1843 mtc.stop;
1844 }
1845 };
1846
1847 /* Send duplicate DeleteCtxReq */
1848 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1849 GTP.send(g_delete_req);
1850 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1851 if (g_ud_first != g_ud_second) {
1852 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1853 mtc.stop;
1854 }
1855 }
1856
1857 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1858 * is handled differently by SGSN (expect "non-existent" cause) */
1859 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1860 GTP.send(g_delete_req);
1861 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1862 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1863 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1864 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1865 mtc.stop;
1866 }
1867 }
1868
1869 setverdict(pass);
1870}
1871testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1872 var BSSGP_ConnHdlr vc_conn;
1873 f_init();
1874 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1875 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001876 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001877}
1878
Alexander Couzens5e307b42018-05-22 18:12:20 +02001879private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1880 /* MS: perform regular attach */
1881 f_TC_attach(id);
1882
1883 /* HLR: cancel the location request */
1884 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1885 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001886
1887 /* ensure no Detach Request got received */
1888 timer T := 5.0;
1889 T.start;
1890 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001891 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001892 T.stop;
1893 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001894 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001895 }
1896 [] T.timeout {
1897 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001898 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001899 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001900 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001901 repeat;
1902 }
1903 }
1904}
1905
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001906/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1907private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1908 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1909
1910 /* first perform regular attach */
1911 f_TC_attach(id);
1912 /* then activate PDP context */
1913 f_pdp_ctx_act(apars);
1914 /* then transceive a downlink PDU */
1915 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1916
1917 /* Send Error indication as response from upload PDU and expect deact towards MS */
1918 f_pdp_ctx_deact_mt(apars, true);
1919}
1920testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1921 var BSSGP_ConnHdlr vc_conn;
1922 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001923 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 +02001924 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001925 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001926}
1927
Alexander Couzens5e307b42018-05-22 18:12:20 +02001928testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1929 /* MS <-> SGSN: GMM Attach
1930 * HLR -> SGSN: Cancel Location Request
1931 * HLR <- SGSN: Cancel Location Ack
1932 */
1933 var BSSGP_ConnHdlr vc_conn;
1934 f_init();
1935 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001936 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001937 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001938 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02001939}
1940
1941
Alexander Couzensc87967a2018-05-22 16:09:54 +02001942private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1943 /* MS: perform regular attach */
1944 f_TC_attach(id);
1945
1946 /* HLR: cancel the location request */
1947 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1948 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1949 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1950
1951 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02001952 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001953 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001954
1955 setverdict(pass);
1956}
1957
1958testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1959 /* MS <-> SGSN: GMM Attach
1960 * HLR -> SGSN: Cancel Location Request
1961 * HLR <- SGSN: Cancel Location Ack
1962 * MS <- SGSN: Detach Request
1963 * SGSN-> MS: Detach Complete
1964 */
1965 var BSSGP_ConnHdlr vc_conn;
1966 f_init();
1967 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001968 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001969 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001970 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02001971}
1972
1973
Alexander Couzens6c47f292018-05-22 17:09:49 +02001974private function f_hlr_location_cancel_request_unknown_subscriber(
1975 charstring id,
1976 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1977
1978 /* HLR: cancel the location request */
1979 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1980
1981 /* cause 2 = IMSI_UNKNOWN */
1982 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1983
1984 setverdict(pass);
1985}
1986
1987private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001988 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001989}
1990
1991testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1992 /* HLR -> SGSN: Cancel Location Request
1993 * HLR <- SGSN: Cancel Location Error
1994 */
1995
1996 var BSSGP_ConnHdlr vc_conn;
1997 f_init();
1998 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001999 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002000 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002001 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002002}
2003
2004private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002005 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002006}
2007
2008testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2009 /* HLR -> SGSN: Cancel Location Request
2010 * HLR <- SGSN: Cancel Location Error
2011 */
2012
2013 var BSSGP_ConnHdlr vc_conn;
2014 f_init();
2015 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002016 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 +02002017 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002018 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002019}
2020
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002021private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2022 f_TC_attach(id);
2023 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2024}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002025
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002026testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2027 /* MS <-> SGSN: Attach
2028 * MS -> SGSN: Detach Req (Power off)
2029 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2030 */
2031 var BSSGP_ConnHdlr vc_conn;
2032 var integer id := 33;
2033 var charstring imsi := hex2str(f_gen_imsi(id));
2034
2035 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002036 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002037 vc_conn.done;
2038
2039 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002040 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002041}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002042
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002043/* Attempt an attach, but loose the Identification Request (IMEI) */
2044private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2045 var integer count_req := 0;
2046 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2047
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002048 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002049
2050 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002051 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002052 /* break */
2053 }
Harald Welte955aa942019-05-03 01:29:29 +02002054 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002055 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002056 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002057 repeat;
2058 }
Harald Welte955aa942019-05-03 01:29:29 +02002059 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002060 /* ignore ID REQ IMEI */
2061 count_req := count_req + 1;
2062 repeat;
2063 }
2064 }
2065 if (count_req != 5) {
2066 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002067 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002068 }
2069 setverdict(pass);
2070}
2071
2072testcase TC_attach_no_imei_response() runs on test_CT {
2073 /* MS -> SGSN: Attach Request IMSI
2074 * MS <- SGSN: Identity Request IMSI (optional)
2075 * MS -> SGSN: Identity Response IMSI (optional)
2076 * MS <- SGSN: Identity Request IMEI
2077 * MS -x SGSN: no response
2078 * MS <- SGSN: re-send: Identity Request IMEI 4x
2079 * MS <- SGSN: Attach Reject
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_attach_no_imei_response), testcasename(), g_gb, 32, 60.0);
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002085 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002086 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002087}
2088
Alexander Couzens53f20562018-06-12 16:24:12 +02002089/* Attempt an attach, but loose the Identification Request (IMSI) */
2090private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2091 var integer count_req := 0;
2092 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2093
2094 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2095 g_pars.p_tmsi := 'c0000035'O;
2096
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002097 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02002098
2099 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002100 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002101 /* break */
2102 }
Harald Welte955aa942019-05-03 01:29:29 +02002103 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002104 /* ignore ID REQ IMSI */
2105 count_req := count_req + 1;
2106 repeat;
2107 }
Harald Welte955aa942019-05-03 01:29:29 +02002108 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002109 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002110 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002111 repeat;
2112 }
2113 }
2114 if (count_req != 5) {
2115 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002116 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002117 }
2118 setverdict(pass);
2119}
2120
2121testcase TC_attach_no_imsi_response() runs on test_CT {
2122 /* MS -> SGSN: Attach Request TMSI (unknown)
2123 * MS <- SGSN: Identity Request IMEI (optional)
2124 * MS -> SGSN: Identity Response IMEI (optional)
2125 * MS <- SGSN: Identity Request IMSI
2126 * MS -x SGSN: no response
2127 * MS <- SGSN: re-send: Identity Request IMSI 4x
2128 * MS <- SGSN: Attach Reject
2129 */
2130 var BSSGP_ConnHdlr vc_conn;
2131 f_init();
2132 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002133 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 +02002134 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002135 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002136}
2137
Alexander Couzenscf818962018-06-05 18:00:00 +02002138private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2139 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2140}
2141
2142testcase TC_attach_check_subscriber_list() runs on test_CT {
2143 /* MS <-> SGSN: Attach
2144 * VTY -> SGSN: Check if MS is in subscriber cache
2145 */
2146 var BSSGP_ConnHdlr vc_conn;
2147 var integer id := 34;
2148 var charstring imsi := hex2str(f_gen_imsi(id));
2149
2150 f_init();
2151 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002152 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002153 vc_conn.done;
2154
2155 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2156 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002157 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002158}
2159
Alexander Couzensf9858652018-06-07 16:14:53 +02002160private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2161 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002162 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002163
2164 /* unregister the old IMSI */
2165 f_bssgp_client_unregister(g_pars.imsi);
2166 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002167 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002168 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002169
2170 /* there is no auth */
2171 g_pars.net.expect_auth := false;
2172
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002173 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002174 f_gmm_auth();
2175 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002176 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002177 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002178 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002179 }
Harald Welte955aa942019-05-03 01:29:29 +02002180 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2181 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002182 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002183 setverdict(pass);
2184 }
2185 }
2186}
Alexander Couzens03d12242018-08-07 16:13:52 +02002187
2188private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2189
2190 f_TC_attach_closed_foreign(id);
2191 f_TC_attach_closed_imsi_added(id);
2192
2193}
2194
2195
Alexander Couzensf9858652018-06-07 16:14:53 +02002196testcase TC_attach_closed_add_vty() runs on test_CT {
2197 /* VTY-> SGSN: policy close
2198 * MS -> SGSN: Attach Request
2199 * MS <- SGSN: Identity Request IMSI
2200 * MS -> SGSN: Identity Response IMSI
2201 * MS <- SGSN: Attach Reject
2202 * VTY-> SGSN: policy imsi-acl add IMSI
2203 * MS -> SGSN: Attach Request
2204 * MS <- SGSN: Identity Request IMSI
2205 * MS -> SGSN: Identity Response IMSI
2206 * MS <- SGSN: Identity Request IMEI
2207 * MS -> SGSN: Identity Response IMEI
2208 * MS <- SGSN: Attach Accept
2209 */
2210 var BSSGP_ConnHdlr vc_conn;
2211 f_init();
2212 f_sleep(1.0);
2213 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2214 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002215 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2216 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002217 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002218 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002219 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002220 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002221}
2222
Alexander Couzens0085bd72018-06-12 19:08:44 +02002223/* Attempt an attach, but never answer a Attach Complete */
2224private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2225 var integer count_req := 0;
2226
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002227 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02002228 f_gmm_auth();
2229
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002230 timer T := 10.0;
2231 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002232 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002233 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002234 /* break */
2235 }
Harald Welte955aa942019-05-03 01:29:29 +02002236 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002237 /* ignore */
2238 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002239 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002240 repeat;
2241 }
2242 }
2243 if (count_req != 5) {
2244 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002245 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002246 }
2247 setverdict(pass);
2248}
2249
2250testcase TC_attach_check_complete_resend() runs on test_CT {
2251 /* MS -> SGSN: Attach Request IMSI
2252 * MS <- SGSN: Identity Request *
2253 * MS -> SGSN: Identity Response *
2254 * MS <- SGSN: Attach Complete 5x
2255 */
2256 var BSSGP_ConnHdlr vc_conn;
2257 f_init();
2258 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002259 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 +02002260 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002261 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002262}
2263
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002264private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002265 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002266
2267 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002268 f_send_l3_gmm_llc(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 +02002269 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002270 [] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2271 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002272 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002273 setverdict(pass);
2274 }
Harald Welte955aa942019-05-03 01:29:29 +02002275 [] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002276 setverdict(fail, "Unexpected RAU Reject");
2277 mtc.stop;
2278 }
2279 [] BSSGP[bssgp].receive { repeat; }
2280 }
2281}
2282
Alexander Couzensbfda9212018-07-31 03:17:33 +02002283private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002284 /* first perform regular attach */
2285 f_TC_attach(id);
2286
2287 /* then send RAU */
2288 f_routing_area_update(g_pars.ra);
2289
2290 /* do another RAU */
2291 f_routing_area_update(g_pars.ra);
2292
2293 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2294}
2295
2296testcase TC_attach_rau_a_a() runs on test_CT {
2297 /* MS <-> SGSN: Successful Attach
2298 * MS -> SGSN: Routing Area Update Request
2299 * MS <- SGSN: Routing Area Update Accept
2300 * MS -> SGSN: Routing Area Update Request
2301 * MS <- SGSN: Routing Area Update Accept
2302 * MS -> SGSN: Detach (PowerOff)
2303 */
2304 var BSSGP_ConnHdlr vc_conn;
2305 f_init();
2306 f_sleep(1.0);
2307 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2308 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002309 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002310}
2311
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002312private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002313 f_TC_attach(id);
2314
2315 log("attach complete sending rau");
2316 f_routing_area_update(g_pars.ra, 0);
2317
2318 log("rau complete unregistering");
2319 f_bssgp_client_unregister(g_pars.imsi);
2320 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2321
2322 log("sending second RAU via different RA");
2323 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2324
2325 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2326}
2327
2328testcase TC_attach_rau_a_b() runs on test_CT {
2329 /* MS <-> SGSN: Successful Attach
2330 * MS -> SGSN: Routing Area _a_ Update Request
2331 * MS <- SGSN: Routing Area _a_ Update Accept
2332 * MS -> SGSN: Routing Area _b_ Update Request
2333 * MS <- SGSN: Routing Area _b_ Update Accept
2334 * MS -> SGSN: Detach (PowerOff)
2335 */
2336 var BSSGP_ConnHdlr vc_conn;
2337 f_init();
2338 f_sleep(1.0);
2339 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2340 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002341 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002342}
2343
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002344private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2345 var integer count_req := 0;
2346 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2347 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002348 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002349
2350 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2351
2352 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002353 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002354 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2355 mtc.stop;
2356 }
Harald Welte955aa942019-05-03 01:29:29 +02002357 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002358 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2359 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2360 repeat;
2361 }
Harald Welte955aa942019-05-03 01:29:29 +02002362 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002363 /* send out a second GMM_Attach Request.
2364 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2365 * of the same content */
2366 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2367 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2368 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2369 }
2370 }
2371 f_sleep(1.0);
2372
2373 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2374 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002375 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002376 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2377 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2378 repeat;
2379 }
Harald Welte955aa942019-05-03 01:29:29 +02002380 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002381 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2382 mtc.stop;
2383 }
Harald Welte955aa942019-05-03 01:29:29 +02002384 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002385 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2386 mtc.stop;
2387 }
Harald Welte955aa942019-05-03 01:29:29 +02002388 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2389 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002390 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2391 setverdict(pass);
2392 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2393 }
2394 }
2395}
2396
2397testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2398 /* Testing if the SGSN ignore Attach Request with the exact same content */
2399 /* MS -> SGSN: Attach Request IMSI
2400 * MS <- SGSN: Identity Request IMSI (optional)
2401 * MS -> SGSN: Identity Response IMSI (optional)
2402 * MS <- SGSN: Identity Request IMEI
2403 * MS -> SGSN: Attach Request (2nd)
2404 * MS <- SGSN: Identity Response IMEI
2405 * MS <- SGSN: Attach Accept
2406 * MS -> SGSN: Attach Complete
2407 */
2408 var BSSGP_ConnHdlr vc_conn;
2409 f_init();
2410 f_sleep(1.0);
2411 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2412 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2413 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002414 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002415}
2416
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002417private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002418 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2419
2420 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2421
2422 /* send Attach Request */
2423 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2424 * 3G auth vectors */
2425 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2426 /* The thing is, if the solSACapability is 'omit', then the
2427 * revisionLevelIndicatior is at the wrong place! */
2428 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2429 f_send_l3_gmm_llc(attach_req);
2430
2431 /* do the auth */
2432 var PDU_L3_MS_SGSN l3_mo;
2433 var PDU_L3_SGSN_MS l3_mt;
2434 var default di := activate(as_mm_identity());
2435
2436 var GSUP_IE auth_tuple;
2437 var template AuthenticationParameterAUTNTLV autn;
2438
2439 g_pars.vec := f_gen_auth_vec_3g();
2440 autn := {
2441 elementIdentifier := '28'O,
2442 lengthIndicator := lengthof(g_pars.vec.autn),
2443 autnValue := g_pars.vec.autn
2444 };
2445 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2446 g_pars.vec.sres,
2447 g_pars.vec.kc,
2448 g_pars.vec.ik,
2449 g_pars.vec.ck,
2450 g_pars.vec.autn,
2451 g_pars.vec.res));
2452 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2453 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2454 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2455
2456 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2457 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002458 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002459
2460 /* send the gmm auth failure with resync IE */
2461 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2462
2463 /* wait for the GSUP resync request */
2464 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2465 g_pars.imsi,
2466 g_pars.vec.auts,
2467 g_pars.vec.rand));
2468
2469 /* generate new key material */
2470 g_pars.vec := f_gen_auth_vec_3g();
2471 autn := {
2472 elementIdentifier := '28'O,
2473 lengthIndicator := lengthof(g_pars.vec.autn),
2474 autnValue := g_pars.vec.autn
2475 };
2476
2477 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2478 g_pars.vec.sres,
2479 g_pars.vec.kc,
2480 g_pars.vec.ik,
2481 g_pars.vec.ck,
2482 g_pars.vec.autn,
2483 g_pars.vec.res));
2484 /* send new key material */
2485 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2486
2487 /* wait for the new Auth Request */
2488 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2489 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002490 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002491 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2492 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2493 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2494 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2495 valueField := substr(g_pars.vec.res, 0, 4)
2496 };
2497 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2498 elementIdentifier := '21'O,
2499 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2500 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2501 };
2502 l3_mo := valueof(auth_ciph_resp);
2503 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2504 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2505 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2506 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2507 }
2508 f_send_l3_gmm_llc(l3_mo);
2509 deactivate(di);
2510
2511 /* Expect SGSN to perform LU with HLR */
2512 f_gmm_gsup_lu_isd();
2513
Harald Welte955aa942019-05-03 01:29:29 +02002514 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2515 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002516 }
2517 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2518 setverdict(pass);
2519}
2520
2521testcase TC_attach_usim_resync() runs on test_CT {
2522 /* MS -> SGSN: Attach Request
2523 * MS <- SGSN: Identity Request IMSI
2524 * MS -> SGSN: Identity Response IMSI
2525 * MS <- SGSN: Identity Request IMEI
2526 * MS -> SGSN: Identity Response IMEI
2527 * HLR<- SGSN: SAI Request
2528 * HLR-> SGSN: SAI Response
2529 * MS <- SGSN: Auth Request
2530 * MS -> SGSN: Auth Failure (with AUTS)
2531 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2532 * HLR-> SGSN: SAI Response (new key material)
2533 * MS <- SGSN: Auth Request (new key material)
2534 * MS -> SGSN: Auth Response
2535 * MS <- SGSN: Attach Accept
2536 * MS -> SGSN: Attach Complete
2537 */
2538 var BSSGP_ConnHdlr vc_conn;
2539 f_init();
2540 f_sleep(1.0);
2541 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2542 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002543 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002544}
2545
Harald Weltea05b8072019-04-23 22:35:05 +02002546
2547/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2548private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2549 f_gmm_attach(false, false);
2550 f_sleep(1.0);
2551 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2552 /* try to detach to check if SGSN is still alive */
2553 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2554}
2555testcase TC_llc_null() runs on test_CT {
2556 var BSSGP_ConnHdlr vc_conn;
2557 f_init();
2558 f_sleep(1.0);
2559 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2560 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002561 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002562}
2563
Harald Welte645a1512019-04-23 23:18:23 +02002564/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2565private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2566 f_gmm_attach(false, false);
2567 f_sleep(1.0);
2568 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002569 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002570 setverdict(pass);
2571}
2572testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2573 var BSSGP_ConnHdlr vc_conn;
2574 f_init();
2575 f_sleep(1.0);
2576 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2577 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002578 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002579}
2580
2581/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2582private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2583 f_gmm_attach(false, false);
2584 f_sleep(1.0);
2585 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002586 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002587 setverdict(pass);
2588}
2589testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2590 var BSSGP_ConnHdlr vc_conn;
2591 f_init();
2592 f_sleep(1.0);
2593 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2594 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002595 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002596}
2597
Harald Welte2aaac1b2019-05-02 10:02:53 +02002598/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2599private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2600 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2601 var template (value) XID_Information xid;
2602 var template XID_Information xid_rx;
2603
2604 /* first perform regular attach */
2605 f_TC_attach(id);
2606 /* then activate PDP context */
2607 f_pdp_ctx_act(apars);
2608
2609 /* start MO XID */
2610 xid := { ts_XID_L3(''O) };
2611 xid_rx := { tr_XID_L3(''O) };
2612 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2613 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002614 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002615 [] as_xid(apars);
2616 }
2617 setverdict(pass);
2618}
2619testcase TC_xid_empty_l3() runs on test_CT {
2620 var BSSGP_ConnHdlr vc_conn;
2621 f_init();
2622 f_sleep(1.0);
2623 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2624 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002625 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002626}
2627
2628private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2629 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2630 var template (value) XID_Information xid;
2631 var template XID_Information xid_rx;
2632
2633 /* first perform regular attach */
2634 f_TC_attach(id);
2635 /* then activate PDP context */
2636 f_pdp_ctx_act(apars);
2637
2638 /* start MO XID */
2639 xid := { ts_XID_N201U(1234) };
2640 xid_rx := { tr_XID_N201U(1234) };
2641 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2642 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002643 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002644 [] as_xid(apars);
2645 }
2646 setverdict(pass);
2647}
2648testcase TC_xid_n201u() runs on test_CT {
2649 var BSSGP_ConnHdlr vc_conn;
2650 f_init();
2651 f_sleep(1.0);
2652 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2653 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002654 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002655}
2656
Alexander Couzens6bee0872019-05-11 01:48:50 +02002657private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2658 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2659
2660 /* first perform regular attach */
2661 f_TC_attach(id);
2662 /* then activate PDP context */
2663 f_pdp_ctx_act(apars);
2664 /* do a normal detach */
2665 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2666}
2667
2668testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2669 /* MS -> SGSN: Attach Request
2670 * MS <-> SGSN: [..]
2671 * MS -> SGSN: Attach Complete
2672 * MS -> SGSN: PDP Activate Request
2673 * MS <- SGSN: PDP Activate Accept
2674 * MS -> SGSN: GMM Detach Request
2675 * MS <- SGSN: GMM Detach Accept
2676 */
2677 var BSSGP_ConnHdlr vc_conn;
2678 f_init();
2679 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2680 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002681 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002682}
Harald Welte645a1512019-04-23 23:18:23 +02002683
2684
Harald Welte5ac31492018-02-15 20:39:13 +01002685control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002686 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002687 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002688 execute( TC_attach_umts_aka_umts_res() );
2689 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002690 execute( TC_attach_auth_id_timeout() );
2691 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002692 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002693 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002694 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002695 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002696 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002697 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002698 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002699 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002700 execute( TC_attach_closed_add_vty(), 20.0 );
2701 execute( TC_attach_check_subscriber_list(), 20.0 );
2702 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002703 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002704 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2705 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2706 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2707 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002708 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002709 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002710 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002711 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002712 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002713 execute( TC_detach_unknown_nopoweroff() );
2714 execute( TC_detach_unknown_poweroff() );
2715 execute( TC_detach_nopoweroff() );
2716 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002717 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002718 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002719 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002720 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002721 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002722 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002723 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002724 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002725 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002726 execute( TC_attach_restart_ctr_echo() );
2727 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002728 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002729 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2730 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002731 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002732 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002733 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002734
Harald Welte2aaac1b2019-05-02 10:02:53 +02002735 execute( TC_xid_empty_l3() );
2736 execute( TC_xid_n201u() );
2737
Harald Weltea05b8072019-04-23 22:35:05 +02002738 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002739 execute( TC_llc_sabm_dm_llgmm() );
2740 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002741}
Harald Welte96a33b02018-02-04 10:36:22 +01002742
2743
2744
2745}