blob: adbcf19454dd1ff43452fa670ceb38a8d8abebd2 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010018import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010019import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010023import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020024import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010025
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from GSUP_Emulation all;
33import from GSUP_Types all;
34import from IPA_Emulation all;
35
Harald Welte26fbb6e2019-04-14 17:32:46 +020036import from RAN_Adapter all;
37import from RAN_Emulation all;
38import from RANAP_Templates all;
39import from RANAP_PDU_Descriptions all;
40import from RANAP_IEs all;
41
Harald Welteeded9ad2018-02-17 20:57:34 +010042import from GTP_Emulation all;
43import from GTP_Templates all;
44import from GTP_CodecPort all;
45import from GTPC_Types all;
46import from GTPU_Types all;
47
Harald Weltea2526a82018-02-18 19:03:36 +010048import from LLC_Types all;
49import from LLC_Templates all;
50
51import from SNDCP_Types all;
52
Harald Weltebd194722018-02-16 22:11:08 +010053import from TELNETasp_PortType all;
54import from Osmocom_VTY_Functions all;
55
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010056import from GSM_RR_Types all;
57
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020058import from MobileL3_MM_Types all;
59
Harald Welteeded9ad2018-02-17 20:57:34 +010060
Harald Welte5ac31492018-02-15 20:39:13 +010061modulepar {
62 /* IP/port on which we run our internal GSUP/HLR emulation */
63 charstring mp_hlr_ip := "127.0.0.1";
64 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010065 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020066 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020067
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 NSConfigurations mp_nsconfig := {
69 {
70 local_udp_port := 21010,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 96,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21011,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 97,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 },
89 {
90 local_udp_port := 21012,
91 local_ip := "127.0.0.1",
92 remote_udp_port := 23000,
93 remote_ip := "127.0.0.1",
94 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020095 nsei := 98,
96 role_sgsn := false,
97 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020098 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020099 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200100
101 RAN_Configurations mp_ranap_cfg := {
102 {
103 transport := RANAP_TRANSPORT_IuCS,
104 sccp_service_type := "mtp3_itu",
105 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
106 own_pc := 195,
107 own_ssn := 142,
108 peer_pc := 188, /* 0.23.4 */
109 peer_ssn := 142,
110 sio := '83'O,
111 rctx := 2
112 }
113 }
Harald Welte5ac31492018-02-15 20:39:13 +0100114};
115
116type record GbInstance {
117 NS_CT vc_NS,
118 BSSGP_CT vc_BSSGP,
119 BssgpConfig cfg
120};
Harald Welte96a33b02018-02-04 10:36:22 +0100121
Harald Welte2fa771f2019-05-02 20:13:53 +0200122const integer NUM_GB := 3;
123type record length(NUM_GB) of GbInstance GbInstances;
124type record length(NUM_GB) of NSConfiguration NSConfigurations;
125type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200126
Harald Welte26fbb6e2019-04-14 17:32:46 +0200127const integer NUM_RNC := 1;
128type record of RAN_Configuration RAN_Configurations;
129
Harald Welte96a33b02018-02-04 10:36:22 +0100130type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200131 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200132 var RAN_Adapter g_ranap[NUM_RNC];
Harald Welte96a33b02018-02-04 10:36:22 +0100133
Harald Welte5ac31492018-02-15 20:39:13 +0100134 var GSUP_Emulation_CT vc_GSUP;
135 var IPA_Emulation_CT vc_GSUP_IPA;
136 /* only to get events from IPA underneath GSUP */
137 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100138
Harald Welteeded9ad2018-02-17 20:57:34 +0100139 var GTP_Emulation_CT vc_GTP;
140
Harald Weltebd194722018-02-16 22:11:08 +0100141 port TELNETasp_PT SGSNVTY;
142
Harald Welte96a33b02018-02-04 10:36:22 +0100143 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200144 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100145};
146
Harald Welte26fbb6e2019-04-14 17:32:46 +0200147type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100148 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100149 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200150 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100151}
152
153type record SGSN_ConnHdlrNetworkPars {
154 boolean expect_ptmsi,
155 boolean expect_auth,
156 boolean expect_ciph
157};
158
159type record BSSGP_ConnHdlrPars {
160 /* IMEI of the simulated ME */
161 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200162 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100163 hexstring imsi,
164 /* MSISDN of the simulated MS (probably unused) */
165 hexstring msisdn,
166 /* P-TMSI allocated to the simulated MS */
167 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100168 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100169 /* TLLI of the simulated MS */
170 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100171 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100172 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200173 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200174 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
175 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100176 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100177 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200178 float t_guard,
179 /* only in IuPS / RANAP case */
180 SCCP_PAR_Address sccp_addr_local,
181 SCCP_PAR_Address sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100182};
183
Alexander Couzens89508702018-07-31 04:16:10 +0200184private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200185 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200186 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
187
188 var RoutingAreaIdentificationV ret := {
189 mccDigit1 := mcc_mnc[0],
190 mccDigit2 := mcc_mnc[1],
191 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200192 mncDigit3 := mcc_mnc[3],
193 mncDigit1 := mcc_mnc[4],
194 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200195 lac := int2oct(cell_id.ra_id.lai.lac, 16),
196 rac := int2oct(cell_id.ra_id.rac, 8)
197 }
198 return ret;
199};
200
Alexander Couzens51114d12018-07-31 18:41:56 +0200201private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
202 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
203 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100204 /* connect lower end of BSSGP emulation with NS upper port */
205 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
206 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
207 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
208
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200209 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100210 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
211}
212
213private function f_init_gsup(charstring id) runs on test_CT {
214 id := id & "-GSUP";
215 var GsupOps ops := {
216 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
217 };
218
219 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
220 vc_GSUP := GSUP_Emulation_CT.create(id);
221
222 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
223 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
224 /* we use this hack to get events like ASP_IPA_EVENT_UP */
225 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
226
227 vc_GSUP.start(GSUP_Emulation.main(ops, id));
228 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
229
230 /* wait for incoming connection to GSUP port before proceeding */
231 timer T := 10.0;
232 T.start;
233 alt {
234 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
235 [] T.timeout {
236 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200237 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100238 }
239 }
240}
241
Harald Welteeded9ad2018-02-17 20:57:34 +0100242private function f_init_gtp(charstring id) runs on test_CT {
243 id := id & "-GTP";
244
245 var GtpEmulationCfg gtp_cfg := {
246 gtpc_bind_ip := mp_ggsn_ip,
247 gtpc_bind_port := GTP1C_PORT,
248 gtpu_bind_ip := mp_ggsn_ip,
249 gtpu_bind_port := GTP1U_PORT,
250 sgsn_role := false
251 };
252
253 vc_GTP := GTP_Emulation_CT.create(id);
254 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
255}
256
Harald Weltebd194722018-02-16 22:11:08 +0100257private function f_init_vty() runs on test_CT {
258 map(self:SGSNVTY, system:SGSNVTY);
259 f_vty_set_prompts(SGSNVTY);
260 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200261 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100262 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
263}
264
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200265private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
266 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200267 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200268 } else {
269 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
270 }
271}
272
Harald Weltebd194722018-02-16 22:11:08 +0100273
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200274/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
275function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200276 var integer i;
277
Harald Welte96a33b02018-02-04 10:36:22 +0100278 if (g_initialized == true) {
279 return;
280 }
281 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100282 g_gb[0].cfg := {
283 nsei := 96,
284 bvci := 196,
285 cell_id := {
286 ra_id := {
287 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100288 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100289 rac := 0
290 },
291 cell_id := 20960
292 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200293 sgsn_role := false,
294 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100295 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200296 g_gb[1].cfg := {
297 nsei := 97,
298 bvci := 210,
299 cell_id := {
300 ra_id := {
301 lai := {
302 mcc_mnc := mcc_mnc, lac := 13200},
303 rac := 0
304 },
305 cell_id := 20961
306 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200307 sgsn_role := false,
308 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200309 };
310 g_gb[2].cfg := {
311 nsei := 98,
312 bvci := 220,
313 cell_id := {
314 ra_id := {
315 lai := {
316 mcc_mnc := mcc_mnc, lac := 13300},
317 rac := 0
318 },
319 cell_id := 20962
320 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200321 sgsn_role := false,
322 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200323 };
Harald Welte96a33b02018-02-04 10:36:22 +0100324
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200325 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200326 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
327 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
328 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200329
330 for (i := 0; i < NUM_RNC; i := i+1) {
331 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
332 f_ran_adapter_start(g_ranap[i]);
333 }
Harald Welte5ac31492018-02-15 20:39:13 +0100334 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100335 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200336 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100337}
Harald Welte96a33b02018-02-04 10:36:22 +0100338
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200339function f_cleanup() runs on test_CT {
340 var integer i;
341 for (i := 0; i < NUM_RNC; i := i+1) {
342 f_ran_adapter_cleanup(g_ranap[i]);
343 }
344 self.stop;
345}
346
Harald Welte26fbb6e2019-04-14 17:32:46 +0200347private function RncUnitdataCallback(RANAP_PDU ranap)
348runs on RAN_Emulation_CT return template RANAP_PDU {
349 var template RANAP_PDU resp := omit;
350
351 log ("RANAP_RncUnitDataCallback");
352 /* answer all RESET with RESET ACK */
353 if (match(ranap, tr_RANAP_Reset)) {
354 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
355 var CN_DomainIndicator dom;
356 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
357 resp := ts_RANAP_ResetAck(dom);
358 }
359 return resp;
360}
361
362const RanOps RNC_RanOps := {
363 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
364 ranap_unitdata_cb := refers(RncUnitdataCallback),
365 ps_domain := true,
366 decode_dtap := true,
367 role_ms := true,
368 protocol := RAN_PROTOCOL_RANAP,
369 transport := RANAP_TRANSPORT_IuCS,
370 use_osmux := false,
371 sccp_addr_local := omit,
372 sccp_addr_peer := omit
373};
374
Harald Welte5ac31492018-02-15 20:39:13 +0100375type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
376
377/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200378function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100379 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100380runs on test_CT return BSSGP_ConnHdlr {
381 var BSSGP_ConnHdlr vc_conn;
382 var SGSN_ConnHdlrNetworkPars net_pars := {
383 expect_ptmsi := true,
384 expect_auth := true,
385 expect_ciph := false
386 };
387 var BSSGP_ConnHdlrPars pars := {
388 imei := f_gen_imei(imsi_suffix),
389 imsi := f_gen_imsi(imsi_suffix),
390 msisdn := f_gen_msisdn(imsi_suffix),
391 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100392 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100393 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100394 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100395 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200396 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200397 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100398 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100399 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200400 t_guard := t_guard,
401 sccp_addr_local := g_ranap[0].sccp_addr_own,
402 sccp_addr_peer := g_ranap[0].sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100403 };
404
405 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200406 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
407 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
408 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
409 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
410 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
411 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100412
Harald Welte26fbb6e2019-04-14 17:32:46 +0200413 /* FIXME: support multiple RNCs */
414 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
415 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
416
Harald Welte5ac31492018-02-15 20:39:13 +0100417 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
418 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
419
Harald Welteeded9ad2018-02-17 20:57:34 +0100420 connect(vc_conn:GTP, vc_GTP:CLIENT);
421 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
422
Harald Welte5ac31492018-02-15 20:39:13 +0100423 vc_conn.start(f_handler_init(fn, id, pars));
424 return vc_conn;
425}
426
Harald Welte62e29582018-02-16 21:17:11 +0100427private altstep as_Tguard() runs on BSSGP_ConnHdlr {
428 [] g_Tguard.timeout {
429 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200430 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100431 }
432}
433
Harald Welte5ac31492018-02-15 20:39:13 +0100434/* first function called in every ConnHdlr */
435private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
436runs on BSSGP_ConnHdlr {
437 /* do some common stuff like setting up g_pars */
438 g_pars := pars;
439
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200440 llc := f_llc_create(false);
441
Harald Welte5ac31492018-02-15 20:39:13 +0100442 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200443 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100444 /* tell GSUP dispatcher to send this IMSI to us */
445 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100446 /* tell GTP dispatcher to send this IMSI to us */
447 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100448
Harald Welte62e29582018-02-16 21:17:11 +0100449 g_Tguard.start(pars.t_guard);
450 activate(as_Tguard());
451
Harald Welte5ac31492018-02-15 20:39:13 +0100452 /* call the user-supplied test case function */
453 fn.apply(id);
454 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100455}
456
457/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100458 * Detach without Attach
459 * SM procedures without attach / RAU
460 * ATTACH / RAU
461 ** with / without authentication
462 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100463 * re-transmissions of LLC frames
464 * PDP Context activation
465 ** with different GGSN config in SGSN VTY
466 ** with different PDP context type (v4/v6/v46)
467 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100468 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100469 */
470
471testcase TC_wait_ns_up() runs on test_CT {
472 f_init();
473 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200474 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100475}
476
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200477friend function is_gb(integer gb_idx) return boolean {
478 return gb_idx < NUM_GB;
479}
480friend function is_iu(integer gb_idx) return boolean {
481 return gb_idx >= NUM_GB;
482}
483
Harald Weltea05b8072019-04-23 22:35:05 +0200484function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
485 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
486 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
487}
488
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200489private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200490 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
491 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
492 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200493 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200494}
495
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200496/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
497function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
498 log("Sending InitialUE: ", l3_mo);
499 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
500 var RANAP_PDU ranap;
501 var LAI lai := {
502 pLMNidentity := '62F224'O,
503 lAC := '1234'O,
504 iE_Extensions := omit
505 };
506 var SAI sai := {
507 pLMNidentity := lai.pLMNidentity,
508 lAC := lai.lAC,
509 sAC := '0000'O, /* FIXME */
510 iE_Extensions := omit
511 };
512 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
513 var GlobalRNC_ID grnc_id := {
514 pLMNidentity := lai.pLMNidentity,
515 rNC_ID := 2342 /* FIXME */
516 };
517
518 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
519 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
520 alt {
521 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
522 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
523 setverdict(fail, "DISC.ind from SCCP");
524 mtc.stop;
525 }
526 }
527}
528
529/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
530function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
531 if (is_iu(gb_index)) {
532 if (g_pars.rnc_send_initial_ue) {
533 g_pars.rnc_send_initial_ue := false;
534 f_send_l3_initial_ue(l3_mo);
535 } else {
536 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
537 }
538 } else {
539 f_send_l3_gmm_llc(l3_mo, gb_index);
540 }
541}
542
Harald Welteca362462019-05-02 20:11:21 +0200543altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100544 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200545 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100546 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200547 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100548 repeat;
549 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200550 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
551 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
552 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
553 repeat;
554 }
555 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100556 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200557 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
558 repeat;
559 }
560 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
561 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
562 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100563 repeat;
564 }
565}
Harald Welte96a33b02018-02-04 10:36:22 +0100566
Harald Welteca362462019-05-02 20:11:21 +0200567/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
568function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
569runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200570 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200571 var PDU_L3_SGSN_MS l3_mt;
572 alt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200573 [is_gb(gb_idx)] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
574 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
575 l3_mt := mt.dtap;
576 }
Harald Welteca362462019-05-02 20:11:21 +0200577 }
578 return l3_mt;
579}
580
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200581/* perform GMM authentication (if expected).
582 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
583 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200584function 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 +0100585 var PDU_L3_MS_SGSN l3_mo;
586 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200587 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100588 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200589 var GSUP_IE auth_tuple;
590 var template AuthenticationParameterAUTNTLV autn;
591
592 if (umts_aka_challenge) {
593 g_pars.vec := f_gen_auth_vec_3g();
594 autn := {
595 elementIdentifier := '28'O,
596 lengthIndicator := lengthof(g_pars.vec.autn),
597 autnValue := g_pars.vec.autn
598 };
599
600 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
601 g_pars.vec.sres,
602 g_pars.vec.kc,
603 g_pars.vec.ik,
604 g_pars.vec.ck,
605 g_pars.vec.autn,
606 g_pars.vec.res));
607 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
608 } else {
609 g_pars.vec := f_gen_auth_vec_2g();
610 autn := omit;
611 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
612 g_pars.vec.sres,
613 g_pars.vec.kc));
614 log("GSUP sends only 2G auth tuple", auth_tuple);
615 }
Harald Welteca362462019-05-02 20:11:21 +0200616
Harald Welte5ac31492018-02-15 20:39:13 +0100617 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
618 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200619
620 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
621 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200622 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100623 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200624 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
625
626 if (umts_aka_challenge and not force_gsm_sres) {
627 /* set UMTS response instead */
628 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
629 valueField := substr(g_pars.vec.res, 0, 4)
630 };
631 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
632 elementIdentifier := '21'O,
633 lengthIndicator := lengthof(g_pars.vec.res) - 4,
634 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
635 };
636 }
637
638 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100639 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
640 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
641 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
642 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
643 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200644 f_send_l3(l3_mo, gb_idx);
645
646 /* Security Mode Command + Complete on Iu case */
647 if (is_iu(gb_idx)) {
648 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
649 key_sts := ?)) {
650 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
651 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
652 }
653 }
Harald Welte76dee092018-02-16 22:12:59 +0100654 } else {
655 /* wait for identity procedure */
656 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100657 }
Harald Welte76dee092018-02-16 22:12:59 +0100658
Harald Welte5ac31492018-02-15 20:39:13 +0100659 deactivate(di);
660}
661
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200662function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100663 g_pars.p_tmsi := p_tmsi;
664 /* update TLLI */
665 g_pars.tlli_old := g_pars.tlli;
666 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200667 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100668}
669
Harald Welte04683d02018-02-16 22:43:45 +0100670function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
671 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100672 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200673 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100674 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200675 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200676 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100677 }
Harald Welte04683d02018-02-16 22:43:45 +0100678 g_pars.ra := aa.routingAreaIdentification;
679 if (ispresent(aa.allocatedPTMSI)) {
680 if (not g_pars.net.expect_ptmsi) {
681 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200682 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100683 }
Harald Weltef70997d2018-02-17 10:11:19 +0100684 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100685 }
686 if (ispresent(aa.msIdentity)) {
687 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200688 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100689 }
690 /* P-TMSI.sig */
691 if (ispresent(aa.ptmsiSignature)) {
692 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
693 }
694 /* updateTimer */
695 // aa.readyTimer
696 /* T3302, T3319, T3323, T3312_ext, T3324 */
697}
698
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200699function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100700 /* mandatory IE */
701 g_pars.ra := ra.routingAreaId;
702 if (ispresent(ra.allocatedPTMSI)) {
703 if (not g_pars.net.expect_ptmsi) {
704 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200705 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100706 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200707 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100708 }
709 if (ispresent(ra.msIdentity)) {
710 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200711 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100712 }
713 /* P-TMSI.sig */
714 if (ispresent(ra.ptmsiSignature)) {
715 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
716 }
717 /* updateTimer */
718 // aa.readyTimer
719 /* T3302, T3319, T3323, T3312_ext, T3324 */
720}
721
722
Harald Welte5a4fa042018-02-16 20:59:21 +0100723function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
724 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
725}
726
Harald Welte23178c52018-02-17 09:36:33 +0100727/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100728private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100729 if (ispresent(g_pars.p_tmsi)) {
730 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
731 } else {
732 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
733 }
734}
735
Harald Welte311ec272018-02-17 09:40:03 +0100736private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100737 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100738 /* Expect MSC to perform LU with HLR */
739 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100740 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
741 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
742 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100743 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
744 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
745}
746
Harald Welteca362462019-05-02 20:11:21 +0200747friend 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 +0100748 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200749 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 +0200750 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100751
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200752 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
753 * 3G auth vectors */
754 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
755 /* The thing is, if the solSACapability is 'omit', then the
756 * revisionLevelIndicatior is at the wrong place! */
757 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
758
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200759 f_send_l3(attach_req, gb_idx);
Harald Welteca362462019-05-02 20:11:21 +0200760 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200761 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100762 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100763
Harald Welteca362462019-05-02 20:11:21 +0200764 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
765 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
766
Harald Welte04683d02018-02-16 22:43:45 +0100767 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200768 f_send_l3(ts_GMM_ATTACH_COMPL, gb_idx);
769
770 /* IuPS case: Expect Iu Release */
771 if (is_iu(gb_idx)) {
772 as_iu_release_compl_disc();
773 }
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200774}
775
776private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
777 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100778 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100779}
780
781testcase TC_attach() runs on test_CT {
782 var BSSGP_ConnHdlr vc_conn;
783 f_init();
784 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200785 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100786 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200787 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100788}
789
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100790testcase TC_attach_mnc3() runs on test_CT {
791 var BSSGP_ConnHdlr vc_conn;
792 f_init('023042'H);
793 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200794 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100795 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200796 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100797}
798
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200799private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
800 f_gmm_attach(true, false);
801 setverdict(pass);
802}
803testcase TC_attach_umts_aka_umts_res() runs on test_CT {
804 var BSSGP_ConnHdlr vc_conn;
805 f_init();
806 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200807 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200808 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200809 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200810}
811
812private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
813 f_gmm_attach(true, true);
814 setverdict(pass);
815}
816testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
817 var BSSGP_ConnHdlr vc_conn;
818 f_init();
819 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200820 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200821 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200822 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200823}
824
Harald Welte5b7c8122018-02-16 21:48:17 +0100825/* MS never responds to ID REQ, expect ATTACH REJECT */
826private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100827 var RoutingAreaIdentificationV old_ra := f_random_RAI();
828
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200829 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100830 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200831 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100832 /* don't send ID Response */
833 repeat;
834 }
Harald Welte955aa942019-05-03 01:29:29 +0200835 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100836 setverdict(pass);
837 }
Harald Welte955aa942019-05-03 01:29:29 +0200838 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100839 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200840 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100841 }
842 }
843}
844testcase TC_attach_auth_id_timeout() runs on test_CT {
845 var BSSGP_ConnHdlr vc_conn;
846 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200847 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 +0100848 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200849 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100850}
851
852/* HLR never responds to SAI REQ, expect ATTACH REJECT */
853private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100854 var RoutingAreaIdentificationV old_ra := f_random_RAI();
855
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200856 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100857 alt {
858 [] as_mm_identity();
859 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
860 }
861 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200862 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100863 setverdict(pass);
864}
865testcase TC_attach_auth_sai_timeout() runs on test_CT {
866 var BSSGP_ConnHdlr vc_conn;
867 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200868 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100869 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200870 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100871}
872
Harald Weltefe253882018-02-17 09:25:00 +0100873/* HLR rejects SAI, expect ATTACH REJECT */
874private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100875 var RoutingAreaIdentificationV old_ra := f_random_RAI();
876
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200877 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100878 alt {
879 [] as_mm_identity();
880 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
881 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
882 }
883 }
Harald Welte955aa942019-05-03 01:29:29 +0200884 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100885 setverdict(pass);
886}
887testcase TC_attach_auth_sai_reject() runs on test_CT {
888 var BSSGP_ConnHdlr vc_conn;
889 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200890 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100891 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200892 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100893}
894
Harald Welte5b7c8122018-02-16 21:48:17 +0100895/* HLR never responds to UL REQ, expect ATTACH REJECT */
896private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200897 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100898 var RoutingAreaIdentificationV old_ra := f_random_RAI();
899
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200900 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100901 f_gmm_auth();
902 /* Expect MSC to perform LU with HLR */
903 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
904 /* Never follow-up with ISD_REQ or UL_RES */
905 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200906 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100907 setverdict(pass);
908 }
Harald Welte955aa942019-05-03 01:29:29 +0200909 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
910 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100911 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200912 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100913 }
914 }
915}
916testcase TC_attach_gsup_lu_timeout() runs on test_CT {
917 var BSSGP_ConnHdlr vc_conn;
918 f_init();
919 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200920 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100921 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200922 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100923}
924
Harald Welteb7c14e92018-02-17 09:29:16 +0100925/* HLR rejects UL REQ, expect ATTACH REJECT */
926private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200927 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100928 var RoutingAreaIdentificationV old_ra := f_random_RAI();
929
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200930 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100931 f_gmm_auth();
932 /* Expect MSC to perform LU with HLR */
933 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
934 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
935 }
936 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200937 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100938 setverdict(pass);
939 }
Harald Welte955aa942019-05-03 01:29:29 +0200940 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
941 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100942 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200943 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100944 }
945 }
946}
947testcase TC_attach_gsup_lu_reject() runs on test_CT {
948 var BSSGP_ConnHdlr vc_conn;
949 f_init();
950 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200951 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100952 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200953 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100954}
955
956
Harald Welte3823e2e2018-02-16 21:53:48 +0100957/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
958private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200959 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100960 var RoutingAreaIdentificationV old_ra := f_random_RAI();
961
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200962 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100963 f_gmm_auth();
964 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100965 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100966
Harald Welte955aa942019-05-03 01:29:29 +0200967 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
968 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100969 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200970 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100971 setverdict(pass);
972}
Harald Welte3823e2e2018-02-16 21:53:48 +0100973testcase TC_attach_combined() runs on test_CT {
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
976 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200977 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100978 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200979 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +0100980}
981
Harald Welte76dee092018-02-16 22:12:59 +0100982/* Attempt of GPRS ATTACH in 'accept all' mode */
983private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200984 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100985 var RoutingAreaIdentificationV old_ra := f_random_RAI();
986
987 g_pars.net.expect_auth := false;
988
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200989 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100990 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +0200991 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
992 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100993 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200994 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100995 setverdict(pass);
996}
997testcase TC_attach_accept_all() runs on test_CT {
998 var BSSGP_ConnHdlr vc_conn;
999 f_init();
1000 f_sleep(1.0);
1001 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001002 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001003 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001004 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001005}
Harald Welte5b7c8122018-02-16 21:48:17 +01001006
Harald Welteb2124b22018-02-16 22:26:56 +01001007/* Attempt of GPRS ATTACH in 'accept all' mode */
1008private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001009 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1010
1011 /* Simulate a foreign IMSI */
1012 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001013 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001014
1015 g_pars.net.expect_auth := false;
1016
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001017 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001018 alt {
1019 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001020 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001021 setverdict(pass);
1022 }
Harald Welte955aa942019-05-03 01:29:29 +02001023 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001024 setverdict(pass);
1025 }
Harald Welte955aa942019-05-03 01:29:29 +02001026 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001027 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001028 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001029 }
Harald Welteb2124b22018-02-16 22:26:56 +01001030 }
1031}
1032testcase TC_attach_closed() runs on test_CT {
1033 var BSSGP_ConnHdlr vc_conn;
1034 f_init();
1035 f_sleep(1.0);
1036 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1037 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001038 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001039 vc_conn.done;
1040 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001041 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001042 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001043 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001044}
1045
Harald Welte04683d02018-02-16 22:43:45 +01001046/* Routing Area Update from Unknown TLLI -> REJECT */
1047private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001048 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1049
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001050 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +01001051 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001052 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +01001053 setverdict(pass);
1054 }
1055 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001056 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001057 }
1058}
1059testcase TC_rau_unknown() runs on test_CT {
1060 var BSSGP_ConnHdlr vc_conn;
1061 f_init();
1062 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001063 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001064 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001065 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001066}
1067
Harald Welte91636de2018-02-17 10:16:14 +01001068private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001069 /* first perform regular attach */
1070 f_TC_attach(id);
1071
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001072 f_routing_area_update(g_pars.ra);
1073
Harald Welte91636de2018-02-17 10:16:14 +01001074}
1075testcase TC_attach_rau() runs on test_CT {
1076 var BSSGP_ConnHdlr vc_conn;
1077 f_init();
1078 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001079 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001080 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001081 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001082}
Harald Welte04683d02018-02-16 22:43:45 +01001083
Harald Welte6abb9fe2018-02-17 15:24:48 +01001084/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001085function 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 +02001086 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001087 timer T := 5.0;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001088 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001089 if (expect_purge) {
1090 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1091 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1092 }
1093 T.start;
1094 alt {
1095 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1096 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001097 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001098 }
Harald Welte955aa942019-05-03 01:29:29 +02001099 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001100 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001101 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001102 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001103 /* TODO: check if any PDP contexts are deactivated on network side? */
1104 }
1105 [power_off] T.timeout {
1106 setverdict(pass);
1107 }
Harald Welte955aa942019-05-03 01:29:29 +02001108 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001109 g_pars.ra := omit;
1110 setverdict(pass);
1111 /* TODO: check if any PDP contexts are deactivated on network side? */
1112 }
Harald Welte955aa942019-05-03 01:29:29 +02001113 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001114 if (power_off) {
1115 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1116 } else {
1117 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1118 }
1119 mtc.stop;
1120 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001121 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001122 }
1123}
1124
1125/* IMSI DETACH (non-power-off) for unknown TLLI */
1126private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1127 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1128}
1129testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1130 var BSSGP_ConnHdlr vc_conn;
1131 f_init();
1132 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001133 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001134 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001135 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001136}
1137
1138/* IMSI DETACH (power-off) for unknown TLLI */
1139private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1140 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1141}
1142testcase TC_detach_unknown_poweroff() runs on test_CT {
1143 var BSSGP_ConnHdlr vc_conn;
1144 f_init();
1145 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001146 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001147 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001148 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001149}
1150
1151/* IMSI DETACH (non-power-off) for known TLLI */
1152private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1153 /* first perform regular attach */
1154 f_TC_attach(id);
1155
1156 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1157}
1158testcase TC_detach_nopoweroff() runs on test_CT {
1159 var BSSGP_ConnHdlr vc_conn;
1160 f_init();
1161 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001162 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001163 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001164 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001165}
1166
1167/* IMSI DETACH (power-off) for known TLLI */
1168private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1169 /* first perform regular attach */
1170 f_TC_attach(id);
1171
1172 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1173}
1174testcase TC_detach_poweroff() runs on test_CT {
1175 var BSSGP_ConnHdlr vc_conn;
1176 f_init();
1177 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001178 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001179 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001180 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001181}
1182
Harald Welteeded9ad2018-02-17 20:57:34 +01001183type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001184 BIT3 tid, /* L3 Transaction ID */
1185 BIT4 nsapi, /* SNDCP NSAPI */
1186 BIT4 sapi, /* LLC SAPI */
1187 QoSV qos, /* QoS parameters */
1188 PDPAddressV addr, /* IP address */
1189 octetstring apn optional, /* APN name */
1190 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1191 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001192 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001193 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001194
Harald Welte822f9102018-02-18 20:39:06 +01001195 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1196 OCT4 ggsn_tei_u, /* GGSN TEI User */
1197 octetstring ggsn_ip_c, /* GGSN IP Control */
1198 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001199 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001200
Harald Welte822f9102018-02-18 20:39:06 +01001201 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1202 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1203 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1204 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001205};
1206
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001207
1208private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1209 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1210 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1211 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1212 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1213 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1214 f_gtp_register_teid(apars.ggsn_tei_c);
1215 f_gtp_register_teid(apars.ggsn_tei_u);
1216}
1217
Harald Weltef7191672019-05-02 20:37:23 +02001218function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1219runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001220 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1221 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001222 var template Recovery_gtpc recovery := omit;
1223
1224 if (send_recovery) {
1225 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1226 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001227
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001228 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001229 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001230 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1231 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1232 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1233 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1234 apars.sgsn_tei_c, apars.gtp_resp_cause,
1235 apars.ggsn_tei_c, apars.ggsn_tei_u,
1236 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001237 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1238 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001239 }
1240 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001241 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001242 setverdict(pass);
1243 }
Harald Welte955aa942019-05-03 01:29:29 +02001244 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001245 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001246 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001247 }
Harald Welte955aa942019-05-03 01:29:29 +02001248 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001249 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001250 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001251 }
Harald Welte955aa942019-05-03 01:29:29 +02001252 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001253 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1254 mtc.stop;
1255 }
Harald Welte955aa942019-05-03 01:29:29 +02001256 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001257 setverdict(pass);
1258 }
Harald Weltef7191672019-05-02 20:37:23 +02001259 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001260 }
1261}
1262
Harald Weltef7191672019-05-02 20:37:23 +02001263function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1264runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001265 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1266 var Gtp1cUnitdata g_ud;
1267
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001268 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001269 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1270 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001271 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001272 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1273 }
1274 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001275 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001276 setverdict(pass);
1277 }
Harald Weltef7191672019-05-02 20:37:23 +02001278 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001279 }
1280}
1281
Harald Weltef7191672019-05-02 20:37:23 +02001282function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1283runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001284 var Gtp1cUnitdata g_ud;
1285 var integer seq_nr := 23;
1286 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1287
Harald Weltef7191672019-05-02 20:37:23 +02001288 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001289 if (error_ind) {
1290 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1291 } else {
1292 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1293 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001294
1295 timer T := 5.0;
1296 T.start;
1297
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001298 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001299 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001300 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001301 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001302 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1303 repeat;
1304 }
1305 [] T.timeout {
1306 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1307 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001308 }
1309}
1310
Harald Welte6f203162018-02-18 22:04:55 +01001311
Harald Welteeded9ad2018-02-17 20:57:34 +01001312/* Table 10.5.156/3GPP TS 24.008 */
1313template (value) QoSV t_QosDefault := {
1314 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1315 delayClass := '100'B, /* best effort */
1316 spare1 := '00'B,
1317 precedenceClass := '010'B, /* normal */
1318 spare2 := '0'B,
1319 peakThroughput := '0000'B, /* subscribed */
1320 meanThroughput := '00000'B, /* subscribed */
1321 spare3 := '000'B,
1322 deliverErroneusSDU := omit,
1323 deliveryOrder := omit,
1324 trafficClass := omit,
1325 maxSDUSize := omit,
1326 maxBitrateUplink := omit,
1327 maxBitrateDownlink := omit,
1328 sduErrorRatio := omit,
1329 residualBER := omit,
1330 trafficHandlingPriority := omit,
1331 transferDelay := omit,
1332 guaranteedBitRateUplink := omit,
1333 guaranteedBitRateDownlink := omit,
1334 sourceStatisticsDescriptor := omit,
1335 signallingIndication := omit,
1336 spare4 := omit,
1337 maxBitrateDownlinkExt := omit,
1338 guaranteedBitRateDownlinkExt := omit,
1339 maxBitrateUplinkExt := omit,
1340 guaranteedBitRateUplinkExt := omit,
1341 maxBitrateDownlinkExt2 := omit,
1342 guaranteedBitRateDownlinkExt2 := omit,
1343 maxBitrateUplinkExt2 := omit,
1344 guaranteedBitRateUplinkExt2 := omit
1345}
1346
1347/* 10.5.6.4 / 3GPP TS 24.008 */
1348template (value) PDPAddressV t_AddrIPv4dyn := {
1349 pdpTypeOrg := '0001'B, /* IETF */
1350 spare := '0000'B,
1351 pdpTypeNum := '21'O, /* IPv4 */
1352 addressInfo := omit
1353}
1354template (value) PDPAddressV t_AddrIPv6dyn := {
1355 pdpTypeOrg := '0001'B, /* IETF */
1356 spare := '0000'B,
1357 pdpTypeNum := '53'O, /* IPv6 */
1358 addressInfo := omit
1359}
1360
Harald Welte37692d82018-02-18 15:21:34 +01001361template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001362 tid := '000'B,
1363 nsapi := '0101'B, /* < 5 are reserved */
1364 sapi := '0011'B, /* 3/5/9/11 */
1365 qos := t_QosDefault,
1366 addr := t_AddrIPv4dyn,
1367 apn := omit,
1368 pco := omit,
1369 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001370 gtp_resp_cause := int2oct(128, 1),
1371 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001372
1373 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001374 ggsn_tei_c := f_rnd_octstring(4),
1375 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001376 ggsn_ip_c := f_inet_addr(ggsn_ip),
1377 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001378 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001379
Harald Welteeded9ad2018-02-17 20:57:34 +01001380 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001381 sgsn_tei_u := omit,
1382 sgsn_ip_c := omit,
1383 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001384}
1385
Harald Welte37692d82018-02-18 15:21:34 +01001386template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1387 connId := 1,
1388 remName := f_inet_ntoa(ip),
1389 remPort := GTP1U_PORT
1390}
1391
1392template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1393 connId := 1,
1394 remName := f_inet_ntoa(ip),
1395 remPort := GTP1C_PORT
1396}
1397
1398private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1399 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1400 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1401}
1402
Harald Weltef7191672019-05-02 20:37:23 +02001403private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001404 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001405 repeat;
1406 }
1407}
1408
1409template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1410 pDU_SN_UNITDATA := {
1411 nsapi := nsapi,
1412 moreBit := ?,
1413 snPduType := '1'B,
1414 firstSegmentIndicator := ?,
1415 spareBit := ?,
1416 pcomp := ?,
1417 dcomp := ?,
1418 npduNumber := ?,
1419 segmentNumber := ?,
1420 npduNumberContinued := ?,
1421 dataSegmentSnUnitdataPdu := payload
1422 }
1423}
1424
1425/* simple case: single segment, no compression */
1426template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1427 pDU_SN_UNITDATA := {
1428 nsapi := nsapi,
1429 moreBit := '0'B,
1430 snPduType := '1'B,
1431 firstSegmentIndicator := '1'B,
1432 spareBit := '0'B,
1433 pcomp := '0000'B,
1434 dcomp := '0000'B,
1435 npduNumber := '0000'B,
1436 segmentNumber := '0000'B,
1437 npduNumberContinued := '00'O,
1438 dataSegmentSnUnitdataPdu := payload
1439 }
1440}
1441
1442/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001443private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1444runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001445 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1446 f_gtpu_send(apars, payload);
1447 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1448 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001449 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001450 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1451 [] BSSGP[gb_idx].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001452 }
1453}
1454
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001455/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001456private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1457runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001458 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1459 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1460 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001461 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001462 /* Expect PDU via GTP from SGSN on simulated GGSN */
1463 alt {
1464 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1465 }
1466}
1467
Harald Welteeded9ad2018-02-17 20:57:34 +01001468private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001469 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001470
1471 /* first perform regular attach */
1472 f_TC_attach(id);
1473
1474 f_pdp_ctx_act(apars);
1475}
1476testcase TC_attach_pdp_act() runs on test_CT {
1477 var BSSGP_ConnHdlr vc_conn;
1478 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001479 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001480 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001481 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001482}
Harald Welteb2124b22018-02-16 22:26:56 +01001483
Harald Welte835b15f2018-02-18 14:39:11 +01001484/* PDP Context activation for not-attached subscriber; expect fail */
1485private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001486 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001487 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001488 apars.apn, apars.pco));
1489 alt {
1490 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001491 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001492 setverdict(pass);
1493 }
1494 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1495 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001496 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001497 }
Harald Welte955aa942019-05-03 01:29:29 +02001498 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001499 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001500 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001501 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001502 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001503 }
1504}
1505testcase TC_pdp_act_unattached() runs on test_CT {
1506 var BSSGP_ConnHdlr vc_conn;
1507 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001508 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001509 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001510 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001511}
1512
Harald Welte37692d82018-02-18 15:21:34 +01001513/* ATTACH + PDP CTX ACT + user plane traffic */
1514private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1515 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1516
1517 /* first perform regular attach */
1518 f_TC_attach(id);
1519 /* then activate PDP context */
1520 f_pdp_ctx_act(apars);
1521 /* then transceive a downlink PDU */
1522 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1523 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1524}
1525testcase TC_attach_pdp_act_user() runs on test_CT {
1526 var BSSGP_ConnHdlr vc_conn;
1527 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001528 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001529 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001530 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001531}
1532
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001533/* ATTACH + PDP CTX ACT; reject from GGSN */
1534private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1535 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1536
1537 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1538 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1539
1540 /* first perform regular attach */
1541 f_TC_attach(id);
1542 /* then activate PDP context */
1543 f_pdp_ctx_act(apars);
1544}
1545testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1546 var BSSGP_ConnHdlr vc_conn;
1547 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001548 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001549 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001550 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001551}
Harald Welte835b15f2018-02-18 14:39:11 +01001552
Harald Welte6f203162018-02-18 22:04:55 +01001553/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1554private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1555 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1556
1557 /* first perform regular attach */
1558 f_TC_attach(id);
1559 /* then activate PDP context */
1560 f_pdp_ctx_act(apars);
1561 /* then transceive a downlink PDU */
1562 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1563 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1564
1565 f_pdp_ctx_deact_mo(apars, '00'O);
1566}
1567testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1568 var BSSGP_ConnHdlr vc_conn;
1569 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001570 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 +01001571 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001572 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001573}
1574
Harald Welte57b9b7f2018-02-18 22:28:13 +01001575/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1576private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1577 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1578
1579 /* first perform regular attach */
1580 f_TC_attach(id);
1581 /* then activate PDP context */
1582 f_pdp_ctx_act(apars);
1583 /* then transceive a downlink PDU */
1584 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1585 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1586
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001587 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001588}
1589testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1590 var BSSGP_ConnHdlr vc_conn;
1591 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001592 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 +01001593 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001594 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001595}
1596
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001597/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1598private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1599 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1600 var Gtp1cUnitdata g_ud;
1601 var integer i;
1602 var OCT1 cause_regular_deact := '24'O;
1603
1604 /* first perform regular attach + PDP context act */
1605 f_TC_attach(id);
1606 f_pdp_ctx_act(apars);
1607
1608 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1609 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1610
1611 for (i := 0; i < 2; i := i+1) {
1612 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1613 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1614 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1615 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1616 }
1617 }
1618
1619 alt {
1620 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1621 setverdict(pass);
1622 }
1623 [] as_xid(apars, 0);
1624 }
1625
1626 /* Make sure second DeactPdpAccept is sent: */
1627 timer T := 2.0;
1628 T.start;
1629 alt {
1630 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1631 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1632 }
1633 [] T.timeout {
1634 setverdict(pass);
1635 }
1636 }
1637
1638 setverdict(pass);
1639}
1640testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1641 var BSSGP_ConnHdlr vc_conn;
1642 f_init();
1643 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1644 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001645 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001646}
1647
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001648/* ATTACH + ATTACH (2nd) */
1649private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1650 g_pars.t_guard := 5.0;
1651
1652 /* first perform regular attach */
1653 f_TC_attach(id);
1654
1655 /* second to perform regular attach */
1656 f_TC_attach(id);
1657}
1658
1659
1660testcase TC_attach_second_attempt() runs on test_CT {
1661 var BSSGP_ConnHdlr vc_conn;
1662 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001663 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001664 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001665 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001666}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001667
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001668private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1669 var Gtp1cUnitdata g_ud;
1670 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1671 var integer seq_nr;
1672
1673 /* first perform regular attach */
1674 f_TC_attach(id);
1675 /* then activate PDP context */
1676 f_pdp_ctx_act(apars);
1677
1678 /* Wait to receive first echo request and send initial Restart counter */
1679 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1680 BSSGP[0].clear;
1681 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1682 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1683 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1684 }
1685
1686 /* At some point next echo request not answered will timeout and SGSN
1687 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1688 timer T := 3.0 * 6.0 + 16.0;
1689 T.start;
1690 alt {
1691 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1692 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1693 setverdict(pass);
1694 }
1695 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1696 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1697 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1698 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1699 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1700 repeat;
1701 }
1702 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1703 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1704 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1705 repeat;
1706 }
1707 [] T.timeout {
1708 setverdict(fail, "BSSGP DeactPdpReq not received");
1709 mtc.stop;
1710 }
1711 [] as_xid(apars);
1712 }
1713 T.stop
1714
1715 setverdict(pass);
1716}
1717/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1718testcase TC_attach_echo_timeout() runs on test_CT {
1719 var BSSGP_ConnHdlr vc_conn;
1720 g_use_echo := true;
1721 f_init();
1722 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1723 vc_conn.done;
1724 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001725 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001726}
1727
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001728private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001729 var Gtp1cUnitdata g_ud;
1730 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1731
1732 /* first perform regular attach */
1733 f_TC_attach(id);
1734 /* Activate a pdp context against the GGSN */
1735 f_pdp_ctx_act(apars);
1736 /* Wait to receive first echo request and send initial Restart counter */
1737 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1738 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1739 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1740 }
1741 /* Wait to receive second echo request and send incremented Restart
1742 counter. This will fake a restarted GGSN, and pdp ctx allocated
1743 should be released by SGSN */
1744 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1745 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1746 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1747 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1748 }
1749 var OCT1 cause_network_failure := int2oct(38, 1)
1750 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001751 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001752 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001753 setverdict(pass);
1754 }
1755 [] as_xid(apars);
1756 }
1757 setverdict(pass);
1758}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001759/* ATTACH + trigger Recovery procedure through EchoResp */
1760testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001761 var BSSGP_ConnHdlr vc_conn;
1762 g_use_echo := true
1763 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001764 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 +02001765 vc_conn.done;
1766 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001767 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001768}
1769
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001770private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1771 var Gtp1cUnitdata g_ud;
1772 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1773 var integer seq_nr := 23;
1774 var GtpPeer peer;
1775 /* first perform regular attach */
1776 f_TC_attach(id);
1777
1778 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1779 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1780 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1781 f_pdp_ctx_act(apars, true);
1782
1783 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1784/* received. */
1785 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1786
1787 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1788 would be great to have an active pdp context here before triggering
1789 Recovery, and making sure the the DEACT request is sent by the SGSN.
1790 */
1791
1792 /* Activate a pdp context against the GGSN, send incremented Recovery
1793 IE. This should trigger the recovery path, but still this specific
1794 CTX activation should work. */
1795 apars.exp_rej_cause := omit; /* default value for tests */
1796 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1797 f_pdp_ctx_act(apars, true);
1798
1799 setverdict(pass);
1800}
1801/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1802testcase TC_attach_restart_ctr_create() runs on test_CT {
1803 var BSSGP_ConnHdlr vc_conn;
1804 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001805 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 +02001806 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001807 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001808}
1809
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001810/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1811private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1812 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1813 var integer seq_nr := 23;
1814 var GtpPeer peer;
1815 var integer i;
1816
1817 /* first perform regular attach */
1818 f_TC_attach(id);
1819 /* then activate PDP context */
1820 f_pdp_ctx_act(apars);
1821
Alexander Couzens0e510e62018-07-28 23:06:00 +02001822 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001823 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1824 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1825
1826 for (i := 0; i < 5; i := i+1) {
1827 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001828 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001829 [] as_xid(apars);
1830 }
1831 }
1832
1833 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1834
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001835 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001836 setverdict(pass);
1837}
1838testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1839 var BSSGP_ConnHdlr vc_conn;
1840 f_init();
1841 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001842 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 +02001843 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001844 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001845}
1846
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001847/* ATTACH + PDP CTX ACT dropped + retrans */
1848private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1849 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1850 var Gtp1cUnitdata g_ud_first, g_ud_second;
1851 /* first perform regular attach */
1852 f_TC_attach(id);
1853
1854 /* then activate PDP context on the Gb side */
1855 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1856 apars.apn, apars.pco), 0);
1857
1858 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1859 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1860 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1861 if (g_ud_first != g_ud_second) {
1862 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1863 mtc.stop;
1864 }
1865 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1866 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1867 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1868 apars.sgsn_tei_c, apars.gtp_resp_cause,
1869 apars.ggsn_tei_c, apars.ggsn_tei_u,
1870 apars.nsapi,
1871 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1872 omit, omit));
1873 }
Harald Welte955aa942019-05-03 01:29:29 +02001874 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001875
1876 /* Now the same with Deact */
1877 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1878 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1879 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1880 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1881 if (g_ud_first != g_ud_second) {
1882 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1883 mtc.stop;
1884 }
1885 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1886 BSSGP[0].clear;
1887 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1888 }
1889 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001890 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001891 setverdict(pass);
1892 }
1893 [] as_xid(apars, 0);
1894 }
1895
1896 setverdict(pass);
1897}
1898testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1899 var BSSGP_ConnHdlr vc_conn;
1900 f_init();
1901 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1902 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001903 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001904}
1905
1906/* Test that SGSN GTP response retransmit queue works fine */
1907private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1908 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1909 var integer seq_nr := 23;
1910 var Gtp1cUnitdata g_ud_first, g_ud_second;
1911 var template Gtp1cUnitdata g_delete_req;
1912 /* first perform regular attach + PDP context act */
1913 f_TC_attach(id);
1914 f_pdp_ctx_act(apars);
1915
1916 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1917 BSSGP[0].clear;
1918 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1919 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1920 GTP.send(g_delete_req);
1921 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001922 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001923 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1924 }
1925 [] as_xid(apars, 0);
1926 }
1927 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1928 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1929 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1930 mtc.stop;
1931 }
1932 };
1933
1934 /* Send duplicate DeleteCtxReq */
1935 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1936 GTP.send(g_delete_req);
1937 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1938 if (g_ud_first != g_ud_second) {
1939 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1940 mtc.stop;
1941 }
1942 }
1943
1944 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1945 * is handled differently by SGSN (expect "non-existent" cause) */
1946 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1947 GTP.send(g_delete_req);
1948 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1949 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1950 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1951 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1952 mtc.stop;
1953 }
1954 }
1955
1956 setverdict(pass);
1957}
1958testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1959 var BSSGP_ConnHdlr vc_conn;
1960 f_init();
1961 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1962 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001963 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001964}
1965
Alexander Couzens5e307b42018-05-22 18:12:20 +02001966private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1967 /* MS: perform regular attach */
1968 f_TC_attach(id);
1969
1970 /* HLR: cancel the location request */
1971 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1972 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001973
1974 /* ensure no Detach Request got received */
1975 timer T := 5.0;
1976 T.start;
1977 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001978 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001979 T.stop;
1980 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001981 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001982 }
1983 [] T.timeout {
1984 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001985 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001986 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001987 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001988 repeat;
1989 }
1990 }
1991}
1992
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001993/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1994private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1995 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1996
1997 /* first perform regular attach */
1998 f_TC_attach(id);
1999 /* then activate PDP context */
2000 f_pdp_ctx_act(apars);
2001 /* then transceive a downlink PDU */
2002 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2003
2004 /* Send Error indication as response from upload PDU and expect deact towards MS */
2005 f_pdp_ctx_deact_mt(apars, true);
2006}
2007testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2008 var BSSGP_ConnHdlr vc_conn;
2009 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002010 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 +02002011 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002012 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002013}
2014
Alexander Couzens5e307b42018-05-22 18:12:20 +02002015testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2016 /* MS <-> SGSN: GMM Attach
2017 * HLR -> SGSN: Cancel Location Request
2018 * HLR <- SGSN: Cancel Location Ack
2019 */
2020 var BSSGP_ConnHdlr vc_conn;
2021 f_init();
2022 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002023 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002024 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002025 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002026}
2027
2028
Alexander Couzensc87967a2018-05-22 16:09:54 +02002029private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2030 /* MS: perform regular attach */
2031 f_TC_attach(id);
2032
2033 /* HLR: cancel the location request */
2034 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2035 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2036 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2037
2038 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002039 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002040 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002041
2042 setverdict(pass);
2043}
2044
2045testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2046 /* MS <-> SGSN: GMM Attach
2047 * HLR -> SGSN: Cancel Location Request
2048 * HLR <- SGSN: Cancel Location Ack
2049 * MS <- SGSN: Detach Request
2050 * SGSN-> MS: Detach Complete
2051 */
2052 var BSSGP_ConnHdlr vc_conn;
2053 f_init();
2054 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002055 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002056 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002057 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002058}
2059
2060
Alexander Couzens6c47f292018-05-22 17:09:49 +02002061private function f_hlr_location_cancel_request_unknown_subscriber(
2062 charstring id,
2063 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2064
2065 /* HLR: cancel the location request */
2066 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2067
2068 /* cause 2 = IMSI_UNKNOWN */
2069 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2070
2071 setverdict(pass);
2072}
2073
2074private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002075 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002076}
2077
2078testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2079 /* HLR -> SGSN: Cancel Location Request
2080 * HLR <- SGSN: Cancel Location Error
2081 */
2082
2083 var BSSGP_ConnHdlr vc_conn;
2084 f_init();
2085 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002086 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 +02002087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002088 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002089}
2090
2091private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002092 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002093}
2094
2095testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2096 /* HLR -> SGSN: Cancel Location Request
2097 * HLR <- SGSN: Cancel Location Error
2098 */
2099
2100 var BSSGP_ConnHdlr vc_conn;
2101 f_init();
2102 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002103 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 +02002104 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002105 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002106}
2107
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002108private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2109 f_TC_attach(id);
2110 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2111}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002112
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002113testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2114 /* MS <-> SGSN: Attach
2115 * MS -> SGSN: Detach Req (Power off)
2116 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2117 */
2118 var BSSGP_ConnHdlr vc_conn;
2119 var integer id := 33;
2120 var charstring imsi := hex2str(f_gen_imsi(id));
2121
2122 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002123 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002124 vc_conn.done;
2125
2126 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002127 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002128}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002129
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002130/* Attempt an attach, but loose the Identification Request (IMEI) */
2131private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2132 var integer count_req := 0;
2133 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2134
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002135 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002136
2137 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002138 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002139 /* break */
2140 }
Harald Welte955aa942019-05-03 01:29:29 +02002141 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002142 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002143 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002144 repeat;
2145 }
Harald Welte955aa942019-05-03 01:29:29 +02002146 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002147 /* ignore ID REQ IMEI */
2148 count_req := count_req + 1;
2149 repeat;
2150 }
2151 }
2152 if (count_req != 5) {
2153 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002154 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002155 }
2156 setverdict(pass);
2157}
2158
2159testcase TC_attach_no_imei_response() runs on test_CT {
2160 /* MS -> SGSN: Attach Request IMSI
2161 * MS <- SGSN: Identity Request IMSI (optional)
2162 * MS -> SGSN: Identity Response IMSI (optional)
2163 * MS <- SGSN: Identity Request IMEI
2164 * MS -x SGSN: no response
2165 * MS <- SGSN: re-send: Identity Request IMEI 4x
2166 * MS <- SGSN: Attach Reject
2167 */
2168 var BSSGP_ConnHdlr vc_conn;
2169 f_init();
2170 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002171 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 +02002172 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002173 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002174}
2175
Alexander Couzens53f20562018-06-12 16:24:12 +02002176/* Attempt an attach, but loose the Identification Request (IMSI) */
2177private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2178 var integer count_req := 0;
2179 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2180
2181 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2182 g_pars.p_tmsi := 'c0000035'O;
2183
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002184 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02002185
2186 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002187 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002188 /* break */
2189 }
Harald Welte955aa942019-05-03 01:29:29 +02002190 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002191 /* ignore ID REQ IMSI */
2192 count_req := count_req + 1;
2193 repeat;
2194 }
Harald Welte955aa942019-05-03 01:29:29 +02002195 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002196 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002197 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002198 repeat;
2199 }
2200 }
2201 if (count_req != 5) {
2202 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002203 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002204 }
2205 setverdict(pass);
2206}
2207
2208testcase TC_attach_no_imsi_response() runs on test_CT {
2209 /* MS -> SGSN: Attach Request TMSI (unknown)
2210 * MS <- SGSN: Identity Request IMEI (optional)
2211 * MS -> SGSN: Identity Response IMEI (optional)
2212 * MS <- SGSN: Identity Request IMSI
2213 * MS -x SGSN: no response
2214 * MS <- SGSN: re-send: Identity Request IMSI 4x
2215 * MS <- SGSN: Attach Reject
2216 */
2217 var BSSGP_ConnHdlr vc_conn;
2218 f_init();
2219 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002220 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 +02002221 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002222 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002223}
2224
Alexander Couzenscf818962018-06-05 18:00:00 +02002225private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2226 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2227}
2228
2229testcase TC_attach_check_subscriber_list() runs on test_CT {
2230 /* MS <-> SGSN: Attach
2231 * VTY -> SGSN: Check if MS is in subscriber cache
2232 */
2233 var BSSGP_ConnHdlr vc_conn;
2234 var integer id := 34;
2235 var charstring imsi := hex2str(f_gen_imsi(id));
2236
2237 f_init();
2238 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002239 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002240 vc_conn.done;
2241
2242 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2243 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002244 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002245}
2246
Alexander Couzensf9858652018-06-07 16:14:53 +02002247private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2248 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002249 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002250
2251 /* unregister the old IMSI */
2252 f_bssgp_client_unregister(g_pars.imsi);
2253 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002254 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002255 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002256
2257 /* there is no auth */
2258 g_pars.net.expect_auth := false;
2259
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002260 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002261 f_gmm_auth();
2262 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002263 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002264 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002265 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002266 }
Harald Welte955aa942019-05-03 01:29:29 +02002267 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2268 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002269 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002270 setverdict(pass);
2271 }
2272 }
2273}
Alexander Couzens03d12242018-08-07 16:13:52 +02002274
2275private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2276
2277 f_TC_attach_closed_foreign(id);
2278 f_TC_attach_closed_imsi_added(id);
2279
2280}
2281
2282
Alexander Couzensf9858652018-06-07 16:14:53 +02002283testcase TC_attach_closed_add_vty() runs on test_CT {
2284 /* VTY-> SGSN: policy close
2285 * MS -> SGSN: Attach Request
2286 * MS <- SGSN: Identity Request IMSI
2287 * MS -> SGSN: Identity Response IMSI
2288 * MS <- SGSN: Attach Reject
2289 * VTY-> SGSN: policy imsi-acl add IMSI
2290 * MS -> SGSN: Attach Request
2291 * MS <- SGSN: Identity Request IMSI
2292 * MS -> SGSN: Identity Response IMSI
2293 * MS <- SGSN: Identity Request IMEI
2294 * MS -> SGSN: Identity Response IMEI
2295 * MS <- SGSN: Attach Accept
2296 */
2297 var BSSGP_ConnHdlr vc_conn;
2298 f_init();
2299 f_sleep(1.0);
2300 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2301 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002302 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2303 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002304 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002305 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002306 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002307 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002308}
2309
Alexander Couzens0085bd72018-06-12 19:08:44 +02002310/* Attempt an attach, but never answer a Attach Complete */
2311private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2312 var integer count_req := 0;
2313
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002314 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02002315 f_gmm_auth();
2316
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002317 timer T := 10.0;
2318 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002319 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002320 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002321 /* break */
2322 }
Harald Welte955aa942019-05-03 01:29:29 +02002323 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002324 /* ignore */
2325 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002326 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002327 repeat;
2328 }
2329 }
2330 if (count_req != 5) {
2331 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002332 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002333 }
2334 setverdict(pass);
2335}
2336
2337testcase TC_attach_check_complete_resend() runs on test_CT {
2338 /* MS -> SGSN: Attach Request IMSI
2339 * MS <- SGSN: Identity Request *
2340 * MS -> SGSN: Identity Response *
2341 * MS <- SGSN: Attach Complete 5x
2342 */
2343 var BSSGP_ConnHdlr vc_conn;
2344 f_init();
2345 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002346 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 +02002347 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002348 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002349}
2350
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002351private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002352 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002353
2354 /* then send RAU */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002355 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002356 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002357 [] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2358 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002359 f_send_l3(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002360 setverdict(pass);
2361 }
Harald Welte955aa942019-05-03 01:29:29 +02002362 [] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002363 setverdict(fail, "Unexpected RAU Reject");
2364 mtc.stop;
2365 }
2366 [] BSSGP[bssgp].receive { repeat; }
2367 }
2368}
2369
Alexander Couzensbfda9212018-07-31 03:17:33 +02002370private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002371 /* first perform regular attach */
2372 f_TC_attach(id);
2373
2374 /* then send RAU */
2375 f_routing_area_update(g_pars.ra);
2376
2377 /* do another RAU */
2378 f_routing_area_update(g_pars.ra);
2379
2380 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2381}
2382
2383testcase TC_attach_rau_a_a() runs on test_CT {
2384 /* MS <-> SGSN: Successful Attach
2385 * MS -> SGSN: Routing Area Update Request
2386 * MS <- SGSN: Routing Area Update Accept
2387 * MS -> SGSN: Routing Area Update Request
2388 * MS <- SGSN: Routing Area Update Accept
2389 * MS -> SGSN: Detach (PowerOff)
2390 */
2391 var BSSGP_ConnHdlr vc_conn;
2392 f_init();
2393 f_sleep(1.0);
2394 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2395 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002396 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002397}
2398
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002399private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002400 f_TC_attach(id);
2401
2402 log("attach complete sending rau");
2403 f_routing_area_update(g_pars.ra, 0);
2404
2405 log("rau complete unregistering");
2406 f_bssgp_client_unregister(g_pars.imsi);
2407 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2408
2409 log("sending second RAU via different RA");
2410 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2411
2412 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2413}
2414
2415testcase TC_attach_rau_a_b() runs on test_CT {
2416 /* MS <-> SGSN: Successful Attach
2417 * MS -> SGSN: Routing Area _a_ Update Request
2418 * MS <- SGSN: Routing Area _a_ Update Accept
2419 * MS -> SGSN: Routing Area _b_ Update Request
2420 * MS <- SGSN: Routing Area _b_ Update Accept
2421 * MS -> SGSN: Detach (PowerOff)
2422 */
2423 var BSSGP_ConnHdlr vc_conn;
2424 f_init();
2425 f_sleep(1.0);
2426 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2427 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002428 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002429}
2430
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002431private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2432 var integer count_req := 0;
2433 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2434 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002435 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002436
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002437 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002438
2439 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002440 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002441 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2442 mtc.stop;
2443 }
Harald Welte955aa942019-05-03 01:29:29 +02002444 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002445 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002446 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002447 repeat;
2448 }
Harald Welte955aa942019-05-03 01:29:29 +02002449 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002450 /* send out a second GMM_Attach Request.
2451 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2452 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002453 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002454 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002455 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002456 }
2457 }
2458 f_sleep(1.0);
2459
2460 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2461 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002462 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002463 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002464 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002465 repeat;
2466 }
Harald Welte955aa942019-05-03 01:29:29 +02002467 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002468 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2469 mtc.stop;
2470 }
Harald Welte955aa942019-05-03 01:29:29 +02002471 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002472 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2473 mtc.stop;
2474 }
Harald Welte955aa942019-05-03 01:29:29 +02002475 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2476 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002477 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002478 setverdict(pass);
2479 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2480 }
2481 }
2482}
2483
2484testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2485 /* Testing if the SGSN ignore Attach Request with the exact same content */
2486 /* MS -> SGSN: Attach Request IMSI
2487 * MS <- SGSN: Identity Request IMSI (optional)
2488 * MS -> SGSN: Identity Response IMSI (optional)
2489 * MS <- SGSN: Identity Request IMEI
2490 * MS -> SGSN: Attach Request (2nd)
2491 * MS <- SGSN: Identity Response IMEI
2492 * MS <- SGSN: Attach Accept
2493 * MS -> SGSN: Attach Complete
2494 */
2495 var BSSGP_ConnHdlr vc_conn;
2496 f_init();
2497 f_sleep(1.0);
2498 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2499 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2500 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002501 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002502}
2503
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002504private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002505 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2506
2507 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2508
2509 /* send Attach Request */
2510 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2511 * 3G auth vectors */
2512 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2513 /* The thing is, if the solSACapability is 'omit', then the
2514 * revisionLevelIndicatior is at the wrong place! */
2515 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002516 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002517
2518 /* do the auth */
2519 var PDU_L3_MS_SGSN l3_mo;
2520 var PDU_L3_SGSN_MS l3_mt;
2521 var default di := activate(as_mm_identity());
2522
2523 var GSUP_IE auth_tuple;
2524 var template AuthenticationParameterAUTNTLV autn;
2525
2526 g_pars.vec := f_gen_auth_vec_3g();
2527 autn := {
2528 elementIdentifier := '28'O,
2529 lengthIndicator := lengthof(g_pars.vec.autn),
2530 autnValue := g_pars.vec.autn
2531 };
2532 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2533 g_pars.vec.sres,
2534 g_pars.vec.kc,
2535 g_pars.vec.ik,
2536 g_pars.vec.ck,
2537 g_pars.vec.autn,
2538 g_pars.vec.res));
2539 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2540 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2541 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2542
2543 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2544 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002545 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002546
2547 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002548 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002549
2550 /* wait for the GSUP resync request */
2551 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2552 g_pars.imsi,
2553 g_pars.vec.auts,
2554 g_pars.vec.rand));
2555
2556 /* generate new key material */
2557 g_pars.vec := f_gen_auth_vec_3g();
2558 autn := {
2559 elementIdentifier := '28'O,
2560 lengthIndicator := lengthof(g_pars.vec.autn),
2561 autnValue := g_pars.vec.autn
2562 };
2563
2564 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2565 g_pars.vec.sres,
2566 g_pars.vec.kc,
2567 g_pars.vec.ik,
2568 g_pars.vec.ck,
2569 g_pars.vec.autn,
2570 g_pars.vec.res));
2571 /* send new key material */
2572 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2573
2574 /* wait for the new Auth Request */
2575 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2576 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002577 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002578 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2579 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2580 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2581 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2582 valueField := substr(g_pars.vec.res, 0, 4)
2583 };
2584 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2585 elementIdentifier := '21'O,
2586 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2587 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2588 };
2589 l3_mo := valueof(auth_ciph_resp);
2590 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2591 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2592 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2593 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2594 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002595 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002596 deactivate(di);
2597
2598 /* Expect SGSN to perform LU with HLR */
2599 f_gmm_gsup_lu_isd();
2600
Harald Welte955aa942019-05-03 01:29:29 +02002601 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2602 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002603 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002604 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002605 setverdict(pass);
2606}
2607
2608testcase TC_attach_usim_resync() runs on test_CT {
2609 /* MS -> SGSN: Attach Request
2610 * MS <- SGSN: Identity Request IMSI
2611 * MS -> SGSN: Identity Response IMSI
2612 * MS <- SGSN: Identity Request IMEI
2613 * MS -> SGSN: Identity Response IMEI
2614 * HLR<- SGSN: SAI Request
2615 * HLR-> SGSN: SAI Response
2616 * MS <- SGSN: Auth Request
2617 * MS -> SGSN: Auth Failure (with AUTS)
2618 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2619 * HLR-> SGSN: SAI Response (new key material)
2620 * MS <- SGSN: Auth Request (new key material)
2621 * MS -> SGSN: Auth Response
2622 * MS <- SGSN: Attach Accept
2623 * MS -> SGSN: Attach Complete
2624 */
2625 var BSSGP_ConnHdlr vc_conn;
2626 f_init();
2627 f_sleep(1.0);
2628 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2629 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002630 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002631}
2632
Harald Weltea05b8072019-04-23 22:35:05 +02002633
2634/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2635private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2636 f_gmm_attach(false, false);
2637 f_sleep(1.0);
2638 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2639 /* try to detach to check if SGSN is still alive */
2640 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2641}
2642testcase TC_llc_null() runs on test_CT {
2643 var BSSGP_ConnHdlr vc_conn;
2644 f_init();
2645 f_sleep(1.0);
2646 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2647 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002648 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002649}
2650
Harald Welte645a1512019-04-23 23:18:23 +02002651/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2652private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2653 f_gmm_attach(false, false);
2654 f_sleep(1.0);
2655 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002656 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002657 setverdict(pass);
2658}
2659testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2660 var BSSGP_ConnHdlr vc_conn;
2661 f_init();
2662 f_sleep(1.0);
2663 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2664 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002665 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002666}
2667
2668/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2669private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2670 f_gmm_attach(false, false);
2671 f_sleep(1.0);
2672 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002673 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002674 setverdict(pass);
2675}
2676testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2677 var BSSGP_ConnHdlr vc_conn;
2678 f_init();
2679 f_sleep(1.0);
2680 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2681 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002682 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002683}
2684
Harald Welte2aaac1b2019-05-02 10:02:53 +02002685/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2686private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2687 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2688 var template (value) XID_Information xid;
2689 var template XID_Information xid_rx;
2690
2691 /* first perform regular attach */
2692 f_TC_attach(id);
2693 /* then activate PDP context */
2694 f_pdp_ctx_act(apars);
2695
2696 /* start MO XID */
2697 xid := { ts_XID_L3(''O) };
2698 xid_rx := { tr_XID_L3(''O) };
2699 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2700 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002701 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002702 [] as_xid(apars);
2703 }
2704 setverdict(pass);
2705}
2706testcase TC_xid_empty_l3() runs on test_CT {
2707 var BSSGP_ConnHdlr vc_conn;
2708 f_init();
2709 f_sleep(1.0);
2710 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2711 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002712 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002713}
2714
2715private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2716 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2717 var template (value) XID_Information xid;
2718 var template XID_Information xid_rx;
2719
2720 /* first perform regular attach */
2721 f_TC_attach(id);
2722 /* then activate PDP context */
2723 f_pdp_ctx_act(apars);
2724
2725 /* start MO XID */
2726 xid := { ts_XID_N201U(1234) };
2727 xid_rx := { tr_XID_N201U(1234) };
2728 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2729 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002730 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002731 [] as_xid(apars);
2732 }
2733 setverdict(pass);
2734}
2735testcase TC_xid_n201u() runs on test_CT {
2736 var BSSGP_ConnHdlr vc_conn;
2737 f_init();
2738 f_sleep(1.0);
2739 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2740 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002741 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002742}
2743
Alexander Couzens6bee0872019-05-11 01:48:50 +02002744private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2745 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2746
2747 /* first perform regular attach */
2748 f_TC_attach(id);
2749 /* then activate PDP context */
2750 f_pdp_ctx_act(apars);
2751 /* do a normal detach */
2752 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2753}
2754
2755testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2756 /* MS -> SGSN: Attach Request
2757 * MS <-> SGSN: [..]
2758 * MS -> SGSN: Attach Complete
2759 * MS -> SGSN: PDP Activate Request
2760 * MS <- SGSN: PDP Activate Accept
2761 * MS -> SGSN: GMM Detach Request
2762 * MS <- SGSN: GMM Detach Accept
2763 */
2764 var BSSGP_ConnHdlr vc_conn;
2765 f_init();
2766 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2767 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002768 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002769}
Harald Welte645a1512019-04-23 23:18:23 +02002770
Harald Welte5ac31492018-02-15 20:39:13 +01002771control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002772 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002773 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002774 execute( TC_attach_umts_aka_umts_res() );
2775 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002776 execute( TC_attach_auth_id_timeout() );
2777 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002778 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002779 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002780 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002781 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002782 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002783 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002784 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002785 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002786 execute( TC_attach_closed_add_vty(), 20.0 );
2787 execute( TC_attach_check_subscriber_list(), 20.0 );
2788 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002789 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002790 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2791 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2792 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2793 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002794 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002795 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002796 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002797 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002798 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002799 execute( TC_detach_unknown_nopoweroff() );
2800 execute( TC_detach_unknown_poweroff() );
2801 execute( TC_detach_nopoweroff() );
2802 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002803 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002804 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002805 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002806 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002807 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002808 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002809 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002810 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002811 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002812 execute( TC_attach_restart_ctr_echo() );
2813 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002814 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002815 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2816 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002817 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002818 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002819 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002820
Harald Welte2aaac1b2019-05-02 10:02:53 +02002821 execute( TC_xid_empty_l3() );
2822 execute( TC_xid_n201u() );
2823
Harald Weltea05b8072019-04-23 22:35:05 +02002824 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002825 execute( TC_llc_sabm_dm_llgmm() );
2826 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002827}
Harald Welte96a33b02018-02-04 10:36:22 +01002828
2829
2830
2831}