blob: a7cc57fdeffcefbd2defac9f0fcd8afba889c97c [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte96a33b02018-02-04 10:36:22 +010014import from General_Types all;
15import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010016import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010017import from NS_Types all;
18import from NS_Emulation all;
19import from BSSGP_Types all;
20import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010021import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020022import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010023
24import from MobileL3_CommonIE_Types all;
25import from MobileL3_GMM_SM_Types all;
26import from MobileL3_Types all;
27import from L3_Templates all;
28import from L3_Common all;
29
30import from GSUP_Emulation all;
31import from GSUP_Types all;
32import from IPA_Emulation all;
33
Harald Welte26fbb6e2019-04-14 17:32:46 +020034import from RAN_Adapter all;
35import from RAN_Emulation all;
36import from RANAP_Templates all;
37import from RANAP_PDU_Descriptions all;
38import from RANAP_IEs all;
39
Harald Welteeded9ad2018-02-17 20:57:34 +010040import from GTP_Emulation all;
41import from GTP_Templates all;
42import from GTP_CodecPort all;
43import from GTPC_Types all;
44import from GTPU_Types all;
45
Harald Weltea2526a82018-02-18 19:03:36 +010046import from LLC_Types all;
47import from LLC_Templates all;
48
49import from SNDCP_Types all;
50
Harald Weltebd194722018-02-16 22:11:08 +010051import from TELNETasp_PortType all;
52import from Osmocom_VTY_Functions all;
53
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010054import from GSM_RR_Types all;
55
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020056import from MobileL3_MM_Types all;
57
Harald Welteeded9ad2018-02-17 20:57:34 +010058
Harald Welte5ac31492018-02-15 20:39:13 +010059modulepar {
60 /* IP/port on which we run our internal GSUP/HLR emulation */
61 charstring mp_hlr_ip := "127.0.0.1";
62 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010063 charstring mp_ggsn_ip := "127.0.0.2";
Alexander Couzens2c12b242018-07-31 00:30:11 +020064
Alexander Couzensf3c1b412018-08-24 00:42:51 +020065 NSConfigurations mp_nsconfig := {
66 {
67 local_udp_port := 21010,
68 local_ip := "127.0.0.1",
69 remote_udp_port := 23000,
70 remote_ip := "127.0.0.1",
71 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
74 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020075 },
76 {
77 local_udp_port := 21011,
78 local_ip := "127.0.0.1",
79 remote_udp_port := 23000,
80 remote_ip := "127.0.0.1",
81 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020082 nsei := 97,
83 role_sgsn := false,
84 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020085 },
86 {
87 local_udp_port := 21012,
88 local_ip := "127.0.0.1",
89 remote_udp_port := 23000,
90 remote_ip := "127.0.0.1",
91 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020092 nsei := 98,
93 role_sgsn := false,
94 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020095 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020096 };
Harald Welte26fbb6e2019-04-14 17:32:46 +020097
98 RAN_Configurations mp_ranap_cfg := {
99 {
100 transport := RANAP_TRANSPORT_IuCS,
101 sccp_service_type := "mtp3_itu",
102 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
103 own_pc := 195,
104 own_ssn := 142,
105 peer_pc := 188, /* 0.23.4 */
106 peer_ssn := 142,
107 sio := '83'O,
108 rctx := 2
109 }
110 }
Harald Welte5ac31492018-02-15 20:39:13 +0100111};
112
113type record GbInstance {
114 NS_CT vc_NS,
115 BSSGP_CT vc_BSSGP,
116 BssgpConfig cfg
117};
Harald Welte96a33b02018-02-04 10:36:22 +0100118
Harald Welte2fa771f2019-05-02 20:13:53 +0200119const integer NUM_GB := 3;
120type record length(NUM_GB) of GbInstance GbInstances;
121type record length(NUM_GB) of NSConfiguration NSConfigurations;
122type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200123
Harald Welte26fbb6e2019-04-14 17:32:46 +0200124const integer NUM_RNC := 1;
125type record of RAN_Configuration RAN_Configurations;
126
Harald Welte96a33b02018-02-04 10:36:22 +0100127type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200128 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200129 var RAN_Adapter g_ranap[NUM_RNC];
Harald Welte96a33b02018-02-04 10:36:22 +0100130
Harald Welte5ac31492018-02-15 20:39:13 +0100131 var GSUP_Emulation_CT vc_GSUP;
132 var IPA_Emulation_CT vc_GSUP_IPA;
133 /* only to get events from IPA underneath GSUP */
134 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100135
Harald Welteeded9ad2018-02-17 20:57:34 +0100136 var GTP_Emulation_CT vc_GTP;
137
Harald Weltebd194722018-02-16 22:11:08 +0100138 port TELNETasp_PT SGSNVTY;
139
Harald Welte96a33b02018-02-04 10:36:22 +0100140 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200141 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100142};
143
Harald Welte26fbb6e2019-04-14 17:32:46 +0200144type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100145 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100146 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200147 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100148}
149
150type record SGSN_ConnHdlrNetworkPars {
151 boolean expect_ptmsi,
152 boolean expect_auth,
153 boolean expect_ciph
154};
155
156type record BSSGP_ConnHdlrPars {
157 /* IMEI of the simulated ME */
158 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200159 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100160 hexstring imsi,
161 /* MSISDN of the simulated MS (probably unused) */
162 hexstring msisdn,
163 /* P-TMSI allocated to the simulated MS */
164 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100165 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100166 /* TLLI of the simulated MS */
167 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100168 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100169 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200170 BssgpCellIds bssgp_cell_id,
Harald Welte5ac31492018-02-15 20:39:13 +0100171 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100172 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200173 float t_guard,
174 /* only in IuPS / RANAP case */
175 SCCP_PAR_Address sccp_addr_local,
176 SCCP_PAR_Address sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100177};
178
Alexander Couzens89508702018-07-31 04:16:10 +0200179private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200180 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200181 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
182
183 var RoutingAreaIdentificationV ret := {
184 mccDigit1 := mcc_mnc[0],
185 mccDigit2 := mcc_mnc[1],
186 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200187 mncDigit3 := mcc_mnc[3],
188 mncDigit1 := mcc_mnc[4],
189 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200190 lac := int2oct(cell_id.ra_id.lai.lac, 16),
191 rac := int2oct(cell_id.ra_id.rac, 8)
192 }
193 return ret;
194};
195
Alexander Couzens51114d12018-07-31 18:41:56 +0200196private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
197 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
198 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100199 /* connect lower end of BSSGP emulation with NS upper port */
200 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
201 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
202 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
203
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200204 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100205 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
206}
207
208private function f_init_gsup(charstring id) runs on test_CT {
209 id := id & "-GSUP";
210 var GsupOps ops := {
211 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
212 };
213
214 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
215 vc_GSUP := GSUP_Emulation_CT.create(id);
216
217 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
218 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
219 /* we use this hack to get events like ASP_IPA_EVENT_UP */
220 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
221
222 vc_GSUP.start(GSUP_Emulation.main(ops, id));
223 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
224
225 /* wait for incoming connection to GSUP port before proceeding */
226 timer T := 10.0;
227 T.start;
228 alt {
229 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
230 [] T.timeout {
231 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200232 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100233 }
234 }
235}
236
Harald Welteeded9ad2018-02-17 20:57:34 +0100237private function f_init_gtp(charstring id) runs on test_CT {
238 id := id & "-GTP";
239
240 var GtpEmulationCfg gtp_cfg := {
241 gtpc_bind_ip := mp_ggsn_ip,
242 gtpc_bind_port := GTP1C_PORT,
243 gtpu_bind_ip := mp_ggsn_ip,
244 gtpu_bind_port := GTP1U_PORT,
245 sgsn_role := false
246 };
247
248 vc_GTP := GTP_Emulation_CT.create(id);
249 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
250}
251
Harald Weltebd194722018-02-16 22:11:08 +0100252private function f_init_vty() runs on test_CT {
253 map(self:SGSNVTY, system:SGSNVTY);
254 f_vty_set_prompts(SGSNVTY);
255 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200256 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100257 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
258}
259
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200260private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
261 if (enable) {
262 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval 5");
263 } else {
264 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
265 }
266}
267
Harald Weltebd194722018-02-16 22:11:08 +0100268
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200269/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
270function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200271 var integer i;
272
Harald Welte96a33b02018-02-04 10:36:22 +0100273 if (g_initialized == true) {
274 return;
275 }
276 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100277 g_gb[0].cfg := {
278 nsei := 96,
279 bvci := 196,
280 cell_id := {
281 ra_id := {
282 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100283 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100284 rac := 0
285 },
286 cell_id := 20960
287 },
288 sgsn_role := false
289 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200290 g_gb[1].cfg := {
291 nsei := 97,
292 bvci := 210,
293 cell_id := {
294 ra_id := {
295 lai := {
296 mcc_mnc := mcc_mnc, lac := 13200},
297 rac := 0
298 },
299 cell_id := 20961
300 },
301 sgsn_role := false
302 };
303 g_gb[2].cfg := {
304 nsei := 98,
305 bvci := 220,
306 cell_id := {
307 ra_id := {
308 lai := {
309 mcc_mnc := mcc_mnc, lac := 13300},
310 rac := 0
311 },
312 cell_id := 20962
313 },
314 sgsn_role := false
315 };
Harald Welte96a33b02018-02-04 10:36:22 +0100316
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200317 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200318 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
319 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
320 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200321
322 for (i := 0; i < NUM_RNC; i := i+1) {
323 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
324 f_ran_adapter_start(g_ranap[i]);
325 }
Harald Welte5ac31492018-02-15 20:39:13 +0100326 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100327 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200328 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100329}
Harald Welte96a33b02018-02-04 10:36:22 +0100330
Harald Welte26fbb6e2019-04-14 17:32:46 +0200331private function RncUnitdataCallback(RANAP_PDU ranap)
332runs on RAN_Emulation_CT return template RANAP_PDU {
333 var template RANAP_PDU resp := omit;
334
335 log ("RANAP_RncUnitDataCallback");
336 /* answer all RESET with RESET ACK */
337 if (match(ranap, tr_RANAP_Reset)) {
338 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
339 var CN_DomainIndicator dom;
340 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
341 resp := ts_RANAP_ResetAck(dom);
342 }
343 return resp;
344}
345
346const RanOps RNC_RanOps := {
347 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
348 ranap_unitdata_cb := refers(RncUnitdataCallback),
349 ps_domain := true,
350 decode_dtap := true,
351 role_ms := true,
352 protocol := RAN_PROTOCOL_RANAP,
353 transport := RANAP_TRANSPORT_IuCS,
354 use_osmux := false,
355 sccp_addr_local := omit,
356 sccp_addr_peer := omit
357};
358
Harald Welte5ac31492018-02-15 20:39:13 +0100359type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
360
361/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200362function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100363 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100364runs on test_CT return BSSGP_ConnHdlr {
365 var BSSGP_ConnHdlr vc_conn;
366 var SGSN_ConnHdlrNetworkPars net_pars := {
367 expect_ptmsi := true,
368 expect_auth := true,
369 expect_ciph := false
370 };
371 var BSSGP_ConnHdlrPars pars := {
372 imei := f_gen_imei(imsi_suffix),
373 imsi := f_gen_imsi(imsi_suffix),
374 msisdn := f_gen_msisdn(imsi_suffix),
375 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100376 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100377 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100378 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100379 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200380 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Harald Welte5ac31492018-02-15 20:39:13 +0100381 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100382 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200383 t_guard := t_guard,
384 sccp_addr_local := g_ranap[0].sccp_addr_own,
385 sccp_addr_peer := g_ranap[0].sccp_addr_peer
Harald Welte5ac31492018-02-15 20:39:13 +0100386 };
387
388 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200389 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
390 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
391 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
392 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
393 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
394 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100395
Harald Welte26fbb6e2019-04-14 17:32:46 +0200396 /* FIXME: support multiple RNCs */
397 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
398 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
399
Harald Welte5ac31492018-02-15 20:39:13 +0100400 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
401 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
402
Harald Welteeded9ad2018-02-17 20:57:34 +0100403 connect(vc_conn:GTP, vc_GTP:CLIENT);
404 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
405
Harald Welte5ac31492018-02-15 20:39:13 +0100406 vc_conn.start(f_handler_init(fn, id, pars));
407 return vc_conn;
408}
409
Harald Welte62e29582018-02-16 21:17:11 +0100410private altstep as_Tguard() runs on BSSGP_ConnHdlr {
411 [] g_Tguard.timeout {
412 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200413 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100414 }
415}
416
Harald Welte5ac31492018-02-15 20:39:13 +0100417/* first function called in every ConnHdlr */
418private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
419runs on BSSGP_ConnHdlr {
420 /* do some common stuff like setting up g_pars */
421 g_pars := pars;
422
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200423 llc := f_llc_create(false);
424
Harald Welte5ac31492018-02-15 20:39:13 +0100425 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200426 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100427 /* tell GSUP dispatcher to send this IMSI to us */
428 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100429 /* tell GTP dispatcher to send this IMSI to us */
430 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100431
Harald Welte62e29582018-02-16 21:17:11 +0100432 g_Tguard.start(pars.t_guard);
433 activate(as_Tguard());
434
Harald Welte5ac31492018-02-15 20:39:13 +0100435 /* call the user-supplied test case function */
436 fn.apply(id);
437 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100438}
439
440/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100441 * Detach without Attach
442 * SM procedures without attach / RAU
443 * ATTACH / RAU
444 ** with / without authentication
445 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100446 * re-transmissions of LLC frames
447 * PDP Context activation
448 ** with different GGSN config in SGSN VTY
449 ** with different PDP context type (v4/v6/v46)
450 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100451 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100452 */
453
454testcase TC_wait_ns_up() runs on test_CT {
455 f_init();
456 f_sleep(20.0);
457}
458
Harald Weltea05b8072019-04-23 22:35:05 +0200459function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
460 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
461 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
462}
463
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200464function f_send_l3_gmm_llc(template PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
465 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
466 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
467 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200468 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200469}
470
Harald Welteca362462019-05-02 20:11:21 +0200471altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100472 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Harald Welte955aa942019-05-03 01:29:29 +0200473 [] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100474 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Harald Welteca362462019-05-02 20:11:21 +0200475 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100476 repeat;
477 }
Harald Welte955aa942019-05-03 01:29:29 +0200478 [] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100479 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Harald Welteca362462019-05-02 20:11:21 +0200480 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100481 repeat;
482 }
483}
Harald Welte96a33b02018-02-04 10:36:22 +0100484
Harald Welteca362462019-05-02 20:11:21 +0200485/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
486function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
487runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Harald Welteca362462019-05-02 20:11:21 +0200488 var PDU_L3_SGSN_MS l3_mt;
489 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200490 [] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
Harald Welteca362462019-05-02 20:11:21 +0200491 }
492 return l3_mt;
493}
494
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200495/* perform GMM authentication (if expected).
496 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
497 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200498function 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 +0100499 var PDU_L3_MS_SGSN l3_mo;
500 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200501 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100502 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200503 var GSUP_IE auth_tuple;
504 var template AuthenticationParameterAUTNTLV autn;
505
506 if (umts_aka_challenge) {
507 g_pars.vec := f_gen_auth_vec_3g();
508 autn := {
509 elementIdentifier := '28'O,
510 lengthIndicator := lengthof(g_pars.vec.autn),
511 autnValue := g_pars.vec.autn
512 };
513
514 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
515 g_pars.vec.sres,
516 g_pars.vec.kc,
517 g_pars.vec.ik,
518 g_pars.vec.ck,
519 g_pars.vec.autn,
520 g_pars.vec.res));
521 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
522 } else {
523 g_pars.vec := f_gen_auth_vec_2g();
524 autn := omit;
525 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
526 g_pars.vec.sres,
527 g_pars.vec.kc));
528 log("GSUP sends only 2G auth tuple", auth_tuple);
529 }
Harald Welteca362462019-05-02 20:11:21 +0200530
Harald Welte5ac31492018-02-15 20:39:13 +0100531 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
532 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200533
534 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
535 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200536 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100537 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200538 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
539
540 if (umts_aka_challenge and not force_gsm_sres) {
541 /* set UMTS response instead */
542 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
543 valueField := substr(g_pars.vec.res, 0, 4)
544 };
545 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
546 elementIdentifier := '21'O,
547 lengthIndicator := lengthof(g_pars.vec.res) - 4,
548 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
549 };
550 }
551
552 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100553 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
554 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
555 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
556 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
557 }
Harald Welteca362462019-05-02 20:11:21 +0200558 f_send_l3_gmm_llc(l3_mo, gb_idx);
Harald Welte76dee092018-02-16 22:12:59 +0100559 } else {
560 /* wait for identity procedure */
561 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100562 }
Harald Welte76dee092018-02-16 22:12:59 +0100563
Harald Welte5ac31492018-02-15 20:39:13 +0100564 deactivate(di);
565}
566
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200567function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100568 g_pars.p_tmsi := p_tmsi;
569 /* update TLLI */
570 g_pars.tlli_old := g_pars.tlli;
571 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200572 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100573}
574
Harald Welte04683d02018-02-16 22:43:45 +0100575function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
576 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100577 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200578 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100579 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200580 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200581 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100582 }
Harald Welte04683d02018-02-16 22:43:45 +0100583 g_pars.ra := aa.routingAreaIdentification;
584 if (ispresent(aa.allocatedPTMSI)) {
585 if (not g_pars.net.expect_ptmsi) {
586 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200587 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100588 }
Harald Weltef70997d2018-02-17 10:11:19 +0100589 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100590 }
591 if (ispresent(aa.msIdentity)) {
592 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200593 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100594 }
595 /* P-TMSI.sig */
596 if (ispresent(aa.ptmsiSignature)) {
597 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
598 }
599 /* updateTimer */
600 // aa.readyTimer
601 /* T3302, T3319, T3323, T3312_ext, T3324 */
602}
603
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200604function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100605 /* mandatory IE */
606 g_pars.ra := ra.routingAreaId;
607 if (ispresent(ra.allocatedPTMSI)) {
608 if (not g_pars.net.expect_ptmsi) {
609 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200610 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100611 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200612 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100613 }
614 if (ispresent(ra.msIdentity)) {
615 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200616 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100617 }
618 /* P-TMSI.sig */
619 if (ispresent(ra.ptmsiSignature)) {
620 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
621 }
622 /* updateTimer */
623 // aa.readyTimer
624 /* T3302, T3319, T3323, T3312_ext, T3324 */
625}
626
627
Harald Welte5a4fa042018-02-16 20:59:21 +0100628function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
629 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
630}
631
Harald Welte23178c52018-02-17 09:36:33 +0100632/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100633private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100634 if (ispresent(g_pars.p_tmsi)) {
635 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
636 } else {
637 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
638 }
639}
640
Harald Welte311ec272018-02-17 09:40:03 +0100641private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100642 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100643 /* Expect MSC to perform LU with HLR */
644 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100645 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
646 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
647 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100648 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
649 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
650}
651
Harald Welteca362462019-05-02 20:11:21 +0200652friend 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 +0100653 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200654 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 +0200655 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100656
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200657 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
658 * 3G auth vectors */
659 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
660 /* The thing is, if the solSACapability is 'omit', then the
661 * revisionLevelIndicatior is at the wrong place! */
662 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
663
Harald Welteca362462019-05-02 20:11:21 +0200664 f_send_l3_gmm_llc(attach_req, gb_idx);
665 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200666 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100667 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100668
Harald Welteca362462019-05-02 20:11:21 +0200669 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
670 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
671
Harald Welte04683d02018-02-16 22:43:45 +0100672 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Harald Welteca362462019-05-02 20:11:21 +0200673 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL, gb_idx);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200674}
675
676private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
677 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100678 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100679}
680
681testcase TC_attach() runs on test_CT {
682 var BSSGP_ConnHdlr vc_conn;
683 f_init();
684 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200685 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100686 vc_conn.done;
687}
688
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100689testcase TC_attach_mnc3() runs on test_CT {
690 var BSSGP_ConnHdlr vc_conn;
691 f_init('023042'H);
692 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200693 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100694 vc_conn.done;
695}
696
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200697private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
698 f_gmm_attach(true, false);
699 setverdict(pass);
700}
701testcase TC_attach_umts_aka_umts_res() runs on test_CT {
702 var BSSGP_ConnHdlr vc_conn;
703 f_init();
704 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200705 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200706 vc_conn.done;
707}
708
709private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
710 f_gmm_attach(true, true);
711 setverdict(pass);
712}
713testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
714 var BSSGP_ConnHdlr vc_conn;
715 f_init();
716 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200717 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200718 vc_conn.done;
719}
720
Harald Welte5b7c8122018-02-16 21:48:17 +0100721/* MS never responds to ID REQ, expect ATTACH REJECT */
722private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100723 var RoutingAreaIdentificationV old_ra := f_random_RAI();
724
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200725 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100726 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200727 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100728 /* don't send ID Response */
729 repeat;
730 }
Harald Welte955aa942019-05-03 01:29:29 +0200731 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100732 setverdict(pass);
733 }
Harald Welte955aa942019-05-03 01:29:29 +0200734 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100735 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200736 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100737 }
738 }
739}
740testcase TC_attach_auth_id_timeout() runs on test_CT {
741 var BSSGP_ConnHdlr vc_conn;
742 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200743 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 +0100744 vc_conn.done;
745}
746
747/* HLR never responds to SAI REQ, expect ATTACH REJECT */
748private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100749 var RoutingAreaIdentificationV old_ra := f_random_RAI();
750
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200751 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100752 alt {
753 [] as_mm_identity();
754 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
755 }
756 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200757 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100758 setverdict(pass);
759}
760testcase TC_attach_auth_sai_timeout() runs on test_CT {
761 var BSSGP_ConnHdlr vc_conn;
762 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200763 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100764 vc_conn.done;
765}
766
Harald Weltefe253882018-02-17 09:25:00 +0100767/* HLR rejects SAI, expect ATTACH REJECT */
768private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100769 var RoutingAreaIdentificationV old_ra := f_random_RAI();
770
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200771 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100772 alt {
773 [] as_mm_identity();
774 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
775 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
776 }
777 }
Harald Welte955aa942019-05-03 01:29:29 +0200778 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100779 setverdict(pass);
780}
781testcase TC_attach_auth_sai_reject() runs on test_CT {
782 var BSSGP_ConnHdlr vc_conn;
783 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200784 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100785 vc_conn.done;
786}
787
Harald Welte5b7c8122018-02-16 21:48:17 +0100788/* HLR never responds to UL REQ, expect ATTACH REJECT */
789private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200790 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100791 var RoutingAreaIdentificationV old_ra := f_random_RAI();
792
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200793 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100794 f_gmm_auth();
795 /* Expect MSC to perform LU with HLR */
796 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
797 /* Never follow-up with ISD_REQ or UL_RES */
798 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200799 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100800 setverdict(pass);
801 }
Harald Welte955aa942019-05-03 01:29:29 +0200802 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
803 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100804 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200805 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100806 }
807 }
808}
809testcase TC_attach_gsup_lu_timeout() runs on test_CT {
810 var BSSGP_ConnHdlr vc_conn;
811 f_init();
812 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200813 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100814 vc_conn.done;
815}
816
Harald Welteb7c14e92018-02-17 09:29:16 +0100817/* HLR rejects UL REQ, expect ATTACH REJECT */
818private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200819 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100820 var RoutingAreaIdentificationV old_ra := f_random_RAI();
821
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200822 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100823 f_gmm_auth();
824 /* Expect MSC to perform LU with HLR */
825 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
826 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
827 }
828 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200829 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100830 setverdict(pass);
831 }
Harald Welte955aa942019-05-03 01:29:29 +0200832 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
833 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100834 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200835 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100836 }
837 }
838}
839testcase TC_attach_gsup_lu_reject() runs on test_CT {
840 var BSSGP_ConnHdlr vc_conn;
841 f_init();
842 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200843 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100844 vc_conn.done;
845}
846
847
Harald Welte3823e2e2018-02-16 21:53:48 +0100848/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
849private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200850 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100851 var RoutingAreaIdentificationV old_ra := f_random_RAI();
852
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200853 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100854 f_gmm_auth();
855 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100856 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100857
Harald Welte955aa942019-05-03 01:29:29 +0200858 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
859 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100860 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200861 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100862 setverdict(pass);
863}
Harald Welte3823e2e2018-02-16 21:53:48 +0100864testcase TC_attach_combined() runs on test_CT {
865 var BSSGP_ConnHdlr vc_conn;
866 f_init();
867 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200868 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100869 vc_conn.done;
870}
871
Harald Welte76dee092018-02-16 22:12:59 +0100872/* Attempt of GPRS ATTACH in 'accept all' mode */
873private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200874 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100875 var RoutingAreaIdentificationV old_ra := f_random_RAI();
876
877 g_pars.net.expect_auth := false;
878
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200879 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +0100880 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +0200881 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
882 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100883 }
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200884 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +0100885 setverdict(pass);
886}
887testcase TC_attach_accept_all() runs on test_CT {
888 var BSSGP_ConnHdlr vc_conn;
889 f_init();
890 f_sleep(1.0);
891 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +0200892 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +0100893 vc_conn.done;
894}
Harald Welte5b7c8122018-02-16 21:48:17 +0100895
Harald Welteb2124b22018-02-16 22:26:56 +0100896/* Attempt of GPRS ATTACH in 'accept all' mode */
897private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +0100898 var RoutingAreaIdentificationV old_ra := f_random_RAI();
899
900 /* Simulate a foreign IMSI */
901 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +0200902 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +0100903
904 g_pars.net.expect_auth := false;
905
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200906 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +0100907 alt {
908 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +0200909 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100910 setverdict(pass);
911 }
Harald Welte955aa942019-05-03 01:29:29 +0200912 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +0100913 setverdict(pass);
914 }
Harald Welte955aa942019-05-03 01:29:29 +0200915 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200916 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200917 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +0200918 }
Harald Welteb2124b22018-02-16 22:26:56 +0100919 }
920}
921testcase TC_attach_closed() runs on test_CT {
922 var BSSGP_ConnHdlr vc_conn;
923 f_init();
924 f_sleep(1.0);
925 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
926 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +0200927 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +0100928 vc_conn.done;
929 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +0200930 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +0100931 vc_conn.done;
932}
933
Harald Welte04683d02018-02-16 22:43:45 +0100934/* Routing Area Update from Unknown TLLI -> REJECT */
935private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100936 var RoutingAreaIdentificationV old_ra := f_random_RAI();
937
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200938 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +0100939 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200940 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +0100941 setverdict(pass);
942 }
943 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +0200944 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +0100945 }
946}
947testcase TC_rau_unknown() 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_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +0100952 vc_conn.done;
953}
954
Harald Welte91636de2018-02-17 10:16:14 +0100955private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100956 /* first perform regular attach */
957 f_TC_attach(id);
958
Alexander Couzens5dce90d2018-07-31 03:16:37 +0200959 f_routing_area_update(g_pars.ra);
960
Harald Welte91636de2018-02-17 10:16:14 +0100961}
962testcase TC_attach_rau() runs on test_CT {
963 var BSSGP_ConnHdlr vc_conn;
964 f_init();
965 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200966 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +0100967 vc_conn.done;
968}
Harald Welte04683d02018-02-16 22:43:45 +0100969
Harald Welte6abb9fe2018-02-17 15:24:48 +0100970/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200971function 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 +0200972 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100973 timer T := 5.0;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200974 f_send_l3_gmm_llc(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +0100975 if (expect_purge) {
976 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
977 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
978 }
979 T.start;
980 alt {
981 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
982 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +0200983 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100984 }
Harald Welte955aa942019-05-03 01:29:29 +0200985 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100986 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +0200987 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +0200988 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +0100989 /* TODO: check if any PDP contexts are deactivated on network side? */
990 }
991 [power_off] T.timeout {
992 setverdict(pass);
993 }
Harald Welte955aa942019-05-03 01:29:29 +0200994 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +0100995 g_pars.ra := omit;
996 setverdict(pass);
997 /* TODO: check if any PDP contexts are deactivated on network side? */
998 }
Harald Welte955aa942019-05-03 01:29:29 +0200999 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001000 if (power_off) {
1001 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1002 } else {
1003 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1004 }
1005 mtc.stop;
1006 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001007 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001008 }
1009}
1010
1011/* IMSI DETACH (non-power-off) for unknown TLLI */
1012private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1013 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1014}
1015testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1016 var BSSGP_ConnHdlr vc_conn;
1017 f_init();
1018 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001019 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001020 vc_conn.done;
1021}
1022
1023/* IMSI DETACH (power-off) for unknown TLLI */
1024private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1025 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1026}
1027testcase TC_detach_unknown_poweroff() runs on test_CT {
1028 var BSSGP_ConnHdlr vc_conn;
1029 f_init();
1030 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001031 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001032 vc_conn.done;
1033}
1034
1035/* IMSI DETACH (non-power-off) for known TLLI */
1036private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1037 /* first perform regular attach */
1038 f_TC_attach(id);
1039
1040 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1041}
1042testcase TC_detach_nopoweroff() runs on test_CT {
1043 var BSSGP_ConnHdlr vc_conn;
1044 f_init();
1045 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001046 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001047 vc_conn.done;
1048}
1049
1050/* IMSI DETACH (power-off) for known TLLI */
1051private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1052 /* first perform regular attach */
1053 f_TC_attach(id);
1054
1055 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1056}
1057testcase TC_detach_poweroff() runs on test_CT {
1058 var BSSGP_ConnHdlr vc_conn;
1059 f_init();
1060 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001061 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001062 vc_conn.done;
1063}
1064
Harald Welteeded9ad2018-02-17 20:57:34 +01001065type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001066 BIT3 tid, /* L3 Transaction ID */
1067 BIT4 nsapi, /* SNDCP NSAPI */
1068 BIT4 sapi, /* LLC SAPI */
1069 QoSV qos, /* QoS parameters */
1070 PDPAddressV addr, /* IP address */
1071 octetstring apn optional, /* APN name */
1072 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1073 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001074 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001075 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001076
Harald Welte822f9102018-02-18 20:39:06 +01001077 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1078 OCT4 ggsn_tei_u, /* GGSN TEI User */
1079 octetstring ggsn_ip_c, /* GGSN IP Control */
1080 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001081 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001082
Harald Welte822f9102018-02-18 20:39:06 +01001083 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1084 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1085 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1086 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001087};
1088
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001089
1090private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1091 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1092 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1093 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1094 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1095 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1096 f_gtp_register_teid(apars.ggsn_tei_c);
1097 f_gtp_register_teid(apars.ggsn_tei_u);
1098}
1099
Harald Weltef7191672019-05-02 20:37:23 +02001100function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1101runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001102 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1103 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001104 var template Recovery_gtpc recovery := omit;
1105
1106 if (send_recovery) {
1107 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1108 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001109
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001110 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001111 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001112 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1113 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1114 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1115 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1116 apars.sgsn_tei_c, apars.gtp_resp_cause,
1117 apars.ggsn_tei_c, apars.ggsn_tei_u,
1118 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001119 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1120 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001121 }
1122 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001123 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001124 setverdict(pass);
1125 }
Harald Welte955aa942019-05-03 01:29:29 +02001126 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001127 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001128 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001129 }
Harald Welte955aa942019-05-03 01:29:29 +02001130 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001131 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001132 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001133 }
Harald Welte955aa942019-05-03 01:29:29 +02001134 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001135 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1136 mtc.stop;
1137 }
Harald Welte955aa942019-05-03 01:29:29 +02001138 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001139 setverdict(pass);
1140 }
Harald Weltef7191672019-05-02 20:37:23 +02001141 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001142 }
1143}
1144
Harald Weltef7191672019-05-02 20:37:23 +02001145function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1146runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001147 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1148 var Gtp1cUnitdata g_ud;
1149
Harald Weltef7191672019-05-02 20:37:23 +02001150 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001151 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1152 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001153 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001154 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1155 }
1156 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001157 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001158 setverdict(pass);
1159 }
Harald Weltef7191672019-05-02 20:37:23 +02001160 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001161 }
1162}
1163
Harald Weltef7191672019-05-02 20:37:23 +02001164function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1165runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001166 var Gtp1cUnitdata g_ud;
1167 var integer seq_nr := 23;
1168 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1169
Harald Weltef7191672019-05-02 20:37:23 +02001170 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001171 if (error_ind) {
1172 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1173 } else {
1174 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1175 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001176
1177 timer T := 5.0;
1178 T.start;
1179
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001180 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001181 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Harald Weltef7191672019-05-02 20:37:23 +02001182 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001183 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001184 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1185 repeat;
1186 }
1187 [] T.timeout {
1188 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1189 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001190 }
1191}
1192
Harald Welte6f203162018-02-18 22:04:55 +01001193
Harald Welteeded9ad2018-02-17 20:57:34 +01001194/* Table 10.5.156/3GPP TS 24.008 */
1195template (value) QoSV t_QosDefault := {
1196 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1197 delayClass := '100'B, /* best effort */
1198 spare1 := '00'B,
1199 precedenceClass := '010'B, /* normal */
1200 spare2 := '0'B,
1201 peakThroughput := '0000'B, /* subscribed */
1202 meanThroughput := '00000'B, /* subscribed */
1203 spare3 := '000'B,
1204 deliverErroneusSDU := omit,
1205 deliveryOrder := omit,
1206 trafficClass := omit,
1207 maxSDUSize := omit,
1208 maxBitrateUplink := omit,
1209 maxBitrateDownlink := omit,
1210 sduErrorRatio := omit,
1211 residualBER := omit,
1212 trafficHandlingPriority := omit,
1213 transferDelay := omit,
1214 guaranteedBitRateUplink := omit,
1215 guaranteedBitRateDownlink := omit,
1216 sourceStatisticsDescriptor := omit,
1217 signallingIndication := omit,
1218 spare4 := omit,
1219 maxBitrateDownlinkExt := omit,
1220 guaranteedBitRateDownlinkExt := omit,
1221 maxBitrateUplinkExt := omit,
1222 guaranteedBitRateUplinkExt := omit,
1223 maxBitrateDownlinkExt2 := omit,
1224 guaranteedBitRateDownlinkExt2 := omit,
1225 maxBitrateUplinkExt2 := omit,
1226 guaranteedBitRateUplinkExt2 := omit
1227}
1228
1229/* 10.5.6.4 / 3GPP TS 24.008 */
1230template (value) PDPAddressV t_AddrIPv4dyn := {
1231 pdpTypeOrg := '0001'B, /* IETF */
1232 spare := '0000'B,
1233 pdpTypeNum := '21'O, /* IPv4 */
1234 addressInfo := omit
1235}
1236template (value) PDPAddressV t_AddrIPv6dyn := {
1237 pdpTypeOrg := '0001'B, /* IETF */
1238 spare := '0000'B,
1239 pdpTypeNum := '53'O, /* IPv6 */
1240 addressInfo := omit
1241}
1242
Harald Welte37692d82018-02-18 15:21:34 +01001243template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001244 tid := '000'B,
1245 nsapi := '0101'B, /* < 5 are reserved */
1246 sapi := '0011'B, /* 3/5/9/11 */
1247 qos := t_QosDefault,
1248 addr := t_AddrIPv4dyn,
1249 apn := omit,
1250 pco := omit,
1251 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001252 gtp_resp_cause := int2oct(128, 1),
1253 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001254
1255 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001256 ggsn_tei_c := f_rnd_octstring(4),
1257 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001258 ggsn_ip_c := f_inet_addr(ggsn_ip),
1259 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001260 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001261
Harald Welteeded9ad2018-02-17 20:57:34 +01001262 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001263 sgsn_tei_u := omit,
1264 sgsn_ip_c := omit,
1265 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001266}
1267
Harald Welte37692d82018-02-18 15:21:34 +01001268template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1269 connId := 1,
1270 remName := f_inet_ntoa(ip),
1271 remPort := GTP1U_PORT
1272}
1273
1274template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1275 connId := 1,
1276 remName := f_inet_ntoa(ip),
1277 remPort := GTP1C_PORT
1278}
1279
1280private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1281 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1282 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1283}
1284
Harald Weltef7191672019-05-02 20:37:23 +02001285private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001286 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001287 repeat;
1288 }
1289}
1290
1291template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1292 pDU_SN_UNITDATA := {
1293 nsapi := nsapi,
1294 moreBit := ?,
1295 snPduType := '1'B,
1296 firstSegmentIndicator := ?,
1297 spareBit := ?,
1298 pcomp := ?,
1299 dcomp := ?,
1300 npduNumber := ?,
1301 segmentNumber := ?,
1302 npduNumberContinued := ?,
1303 dataSegmentSnUnitdataPdu := payload
1304 }
1305}
1306
1307/* simple case: single segment, no compression */
1308template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1309 pDU_SN_UNITDATA := {
1310 nsapi := nsapi,
1311 moreBit := '0'B,
1312 snPduType := '1'B,
1313 firstSegmentIndicator := '1'B,
1314 spareBit := '0'B,
1315 pcomp := '0000'B,
1316 dcomp := '0000'B,
1317 npduNumber := '0000'B,
1318 segmentNumber := '0000'B,
1319 npduNumberContinued := '00'O,
1320 dataSegmentSnUnitdataPdu := payload
1321 }
1322}
1323
1324/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001325private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1326runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001327 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1328 f_gtpu_send(apars, payload);
1329 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1330 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001331 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001332 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1333 [] BSSGP[gb_idx].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001334 }
1335}
1336
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001337/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001338private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1339runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001340 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1341 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1342 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001343 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001344 /* Expect PDU via GTP from SGSN on simulated GGSN */
1345 alt {
1346 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1347 }
1348}
1349
Harald Welteeded9ad2018-02-17 20:57:34 +01001350private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001351 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001352
1353 /* first perform regular attach */
1354 f_TC_attach(id);
1355
1356 f_pdp_ctx_act(apars);
1357}
1358testcase TC_attach_pdp_act() runs on test_CT {
1359 var BSSGP_ConnHdlr vc_conn;
1360 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001361 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001362 vc_conn.done;
1363}
Harald Welteb2124b22018-02-16 22:26:56 +01001364
Harald Welte835b15f2018-02-18 14:39:11 +01001365/* PDP Context activation for not-attached subscriber; expect fail */
1366private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001367 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001368 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001369 apars.apn, apars.pco));
1370 alt {
1371 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001372 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001373 setverdict(pass);
1374 }
1375 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1376 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001377 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001378 }
Harald Welte955aa942019-05-03 01:29:29 +02001379 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001380 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001381 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001382 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001383 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001384 }
1385}
1386testcase TC_pdp_act_unattached() runs on test_CT {
1387 var BSSGP_ConnHdlr vc_conn;
1388 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001389 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001390 vc_conn.done;
1391}
1392
Harald Welte37692d82018-02-18 15:21:34 +01001393/* ATTACH + PDP CTX ACT + user plane traffic */
1394private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1395 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1396
1397 /* first perform regular attach */
1398 f_TC_attach(id);
1399 /* then activate PDP context */
1400 f_pdp_ctx_act(apars);
1401 /* then transceive a downlink PDU */
1402 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1403 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1404}
1405testcase TC_attach_pdp_act_user() runs on test_CT {
1406 var BSSGP_ConnHdlr vc_conn;
1407 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001408 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001409 vc_conn.done;
1410}
1411
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001412/* ATTACH + PDP CTX ACT; reject from GGSN */
1413private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1414 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1415
1416 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1417 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1418
1419 /* first perform regular attach */
1420 f_TC_attach(id);
1421 /* then activate PDP context */
1422 f_pdp_ctx_act(apars);
1423}
1424testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1425 var BSSGP_ConnHdlr vc_conn;
1426 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001427 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001428 vc_conn.done;
1429}
Harald Welte835b15f2018-02-18 14:39:11 +01001430
Harald Welte6f203162018-02-18 22:04:55 +01001431/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1432private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1433 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1434
1435 /* first perform regular attach */
1436 f_TC_attach(id);
1437 /* then activate PDP context */
1438 f_pdp_ctx_act(apars);
1439 /* then transceive a downlink PDU */
1440 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1441 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1442
1443 f_pdp_ctx_deact_mo(apars, '00'O);
1444}
1445testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1446 var BSSGP_ConnHdlr vc_conn;
1447 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001448 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 +01001449 vc_conn.done;
1450}
1451
Harald Welte57b9b7f2018-02-18 22:28:13 +01001452/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1453private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1454 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1455
1456 /* first perform regular attach */
1457 f_TC_attach(id);
1458 /* then activate PDP context */
1459 f_pdp_ctx_act(apars);
1460 /* then transceive a downlink PDU */
1461 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1462 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1463
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001464 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001465}
1466testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1467 var BSSGP_ConnHdlr vc_conn;
1468 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001469 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 +01001470 vc_conn.done;
1471}
1472
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001473/* ATTACH + ATTACH (2nd) */
1474private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1475 g_pars.t_guard := 5.0;
1476
1477 /* first perform regular attach */
1478 f_TC_attach(id);
1479
1480 /* second to perform regular attach */
1481 f_TC_attach(id);
1482}
1483
1484
1485testcase TC_attach_second_attempt() runs on test_CT {
1486 var BSSGP_ConnHdlr vc_conn;
1487 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001488 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001489 vc_conn.done;
1490}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001491
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001492private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001493 var Gtp1cUnitdata g_ud;
1494 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1495
1496 /* first perform regular attach */
1497 f_TC_attach(id);
1498 /* Activate a pdp context against the GGSN */
1499 f_pdp_ctx_act(apars);
1500 /* Wait to receive first echo request and send initial Restart counter */
1501 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1502 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1503 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1504 }
1505 /* Wait to receive second echo request and send incremented Restart
1506 counter. This will fake a restarted GGSN, and pdp ctx allocated
1507 should be released by SGSN */
1508 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1509 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1510 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1511 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1512 }
1513 var OCT1 cause_network_failure := int2oct(38, 1)
1514 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001515 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001516 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001517 setverdict(pass);
1518 }
1519 [] as_xid(apars);
1520 }
1521 setverdict(pass);
1522}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001523/* ATTACH + trigger Recovery procedure through EchoResp */
1524testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001525 var BSSGP_ConnHdlr vc_conn;
1526 g_use_echo := true
1527 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001528 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 +02001529 vc_conn.done;
1530 g_use_echo := false
1531}
1532
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001533private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1534 var Gtp1cUnitdata g_ud;
1535 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1536 var integer seq_nr := 23;
1537 var GtpPeer peer;
1538 /* first perform regular attach */
1539 f_TC_attach(id);
1540
1541 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1542 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1543 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1544 f_pdp_ctx_act(apars, true);
1545
1546 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1547/* received. */
1548 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1549
1550 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1551 would be great to have an active pdp context here before triggering
1552 Recovery, and making sure the the DEACT request is sent by the SGSN.
1553 */
1554
1555 /* Activate a pdp context against the GGSN, send incremented Recovery
1556 IE. This should trigger the recovery path, but still this specific
1557 CTX activation should work. */
1558 apars.exp_rej_cause := omit; /* default value for tests */
1559 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1560 f_pdp_ctx_act(apars, true);
1561
1562 setverdict(pass);
1563}
1564/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1565testcase TC_attach_restart_ctr_create() runs on test_CT {
1566 var BSSGP_ConnHdlr vc_conn;
1567 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001568 vc_conn := f_start_handler(refers(f_TC_attach_restart_ctr_create), testcasename(), g_gb, 24, 30.0);
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001569 vc_conn.done;
1570}
1571
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001572/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1573private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1574 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1575 var integer seq_nr := 23;
1576 var GtpPeer peer;
1577 var integer i;
1578
1579 /* first perform regular attach */
1580 f_TC_attach(id);
1581 /* then activate PDP context */
1582 f_pdp_ctx_act(apars);
1583
Alexander Couzens0e510e62018-07-28 23:06:00 +02001584 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001585 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1586 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1587
1588 for (i := 0; i < 5; i := i+1) {
1589 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001590 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001591 [] as_xid(apars);
1592 }
1593 }
1594
1595 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1596
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001597 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001598 setverdict(pass);
1599}
1600testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1601 var BSSGP_ConnHdlr vc_conn;
1602 f_init();
1603 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001604 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 +02001605 vc_conn.done;
1606}
1607
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001608/* ATTACH + PDP CTX ACT dropped + retrans */
1609private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1610 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1611 var Gtp1cUnitdata g_ud_first, g_ud_second;
1612 /* first perform regular attach */
1613 f_TC_attach(id);
1614
1615 /* then activate PDP context on the Gb side */
1616 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1617 apars.apn, apars.pco), 0);
1618
1619 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1620 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1621 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1622 if (g_ud_first != g_ud_second) {
1623 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1624 mtc.stop;
1625 }
1626 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1627 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1628 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1629 apars.sgsn_tei_c, apars.gtp_resp_cause,
1630 apars.ggsn_tei_c, apars.ggsn_tei_u,
1631 apars.nsapi,
1632 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1633 omit, omit));
1634 }
Harald Welte955aa942019-05-03 01:29:29 +02001635 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001636
1637 /* Now the same with Deact */
1638 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1639 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1640 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1641 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1642 if (g_ud_first != g_ud_second) {
1643 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1644 mtc.stop;
1645 }
1646 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1647 BSSGP[0].clear;
1648 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1649 }
1650 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001651 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001652 setverdict(pass);
1653 }
1654 [] as_xid(apars, 0);
1655 }
1656
1657 setverdict(pass);
1658}
1659testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1660 var BSSGP_ConnHdlr vc_conn;
1661 f_init();
1662 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1663 vc_conn.done;
1664}
1665
1666/* Test that SGSN GTP response retransmit queue works fine */
1667private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1668 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1669 var integer seq_nr := 23;
1670 var Gtp1cUnitdata g_ud_first, g_ud_second;
1671 var template Gtp1cUnitdata g_delete_req;
1672 /* first perform regular attach + PDP context act */
1673 f_TC_attach(id);
1674 f_pdp_ctx_act(apars);
1675
1676 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1677 BSSGP[0].clear;
1678 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1679 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1680 GTP.send(g_delete_req);
1681 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001682 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001683 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1684 }
1685 [] as_xid(apars, 0);
1686 }
1687 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1688 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1689 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1690 mtc.stop;
1691 }
1692 };
1693
1694 /* Send duplicate DeleteCtxReq */
1695 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1696 GTP.send(g_delete_req);
1697 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1698 if (g_ud_first != g_ud_second) {
1699 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1700 mtc.stop;
1701 }
1702 }
1703
1704 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1705 * is handled differently by SGSN (expect "non-existent" cause) */
1706 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1707 GTP.send(g_delete_req);
1708 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1709 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1710 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1711 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1712 mtc.stop;
1713 }
1714 }
1715
1716 setverdict(pass);
1717}
1718testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1719 var BSSGP_ConnHdlr vc_conn;
1720 f_init();
1721 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1722 vc_conn.done;
1723}
1724
Alexander Couzens5e307b42018-05-22 18:12:20 +02001725private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1726 /* MS: perform regular attach */
1727 f_TC_attach(id);
1728
1729 /* HLR: cancel the location request */
1730 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1731 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001732
1733 /* ensure no Detach Request got received */
1734 timer T := 5.0;
1735 T.start;
1736 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001737 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001738 T.stop;
1739 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001740 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001741 }
1742 [] T.timeout {
1743 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001744 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001745 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001746 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001747 repeat;
1748 }
1749 }
1750}
1751
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001752/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
1753private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
1754 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1755
1756 /* first perform regular attach */
1757 f_TC_attach(id);
1758 /* then activate PDP context */
1759 f_pdp_ctx_act(apars);
1760 /* then transceive a downlink PDU */
1761 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1762
1763 /* Send Error indication as response from upload PDU and expect deact towards MS */
1764 f_pdp_ctx_deact_mt(apars, true);
1765}
1766testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
1767 var BSSGP_ConnHdlr vc_conn;
1768 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001769 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 +02001770 vc_conn.done;
1771}
1772
Alexander Couzens5e307b42018-05-22 18:12:20 +02001773testcase TC_hlr_location_cancel_request_update() runs on test_CT {
1774 /* MS <-> SGSN: GMM Attach
1775 * HLR -> SGSN: Cancel Location Request
1776 * HLR <- SGSN: Cancel Location Ack
1777 */
1778 var BSSGP_ConnHdlr vc_conn;
1779 f_init();
1780 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001781 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02001782 vc_conn.done;
1783}
1784
1785
Alexander Couzensc87967a2018-05-22 16:09:54 +02001786private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
1787 /* MS: perform regular attach */
1788 f_TC_attach(id);
1789
1790 /* HLR: cancel the location request */
1791 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
1792 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
1793 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
1794
1795 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02001796 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001797 f_send_l3_gmm_llc(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001798
1799 setverdict(pass);
1800}
1801
1802testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
1803 /* MS <-> SGSN: GMM Attach
1804 * HLR -> SGSN: Cancel Location Request
1805 * HLR <- SGSN: Cancel Location Ack
1806 * MS <- SGSN: Detach Request
1807 * SGSN-> MS: Detach Complete
1808 */
1809 var BSSGP_ConnHdlr vc_conn;
1810 f_init();
1811 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001812 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02001813 vc_conn.done;
1814}
1815
1816
Alexander Couzens6c47f292018-05-22 17:09:49 +02001817private function f_hlr_location_cancel_request_unknown_subscriber(
1818 charstring id,
1819 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
1820
1821 /* HLR: cancel the location request */
1822 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
1823
1824 /* cause 2 = IMSI_UNKNOWN */
1825 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
1826
1827 setverdict(pass);
1828}
1829
1830private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001831 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001832}
1833
1834testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
1835 /* HLR -> SGSN: Cancel Location Request
1836 * HLR <- SGSN: Cancel Location Error
1837 */
1838
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_hlr_location_cancel_request_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001843 vc_conn.done;
1844}
1845
1846private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02001847 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02001848}
1849
1850testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
1851 /* HLR -> SGSN: Cancel Location Request
1852 * HLR <- SGSN: Cancel Location Error
1853 */
1854
1855 var BSSGP_ConnHdlr vc_conn;
1856 f_init();
1857 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001858 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 +02001859 vc_conn.done;
1860}
1861
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001862private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
1863 f_TC_attach(id);
1864 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1865}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001866
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001867testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
1868 /* MS <-> SGSN: Attach
1869 * MS -> SGSN: Detach Req (Power off)
1870 * VTY -> SGSN: Check if MS is NOT in subscriber cache
1871 */
1872 var BSSGP_ConnHdlr vc_conn;
1873 var integer id := 33;
1874 var charstring imsi := hex2str(f_gen_imsi(id));
1875
1876 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001877 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02001878 vc_conn.done;
1879
1880 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1881}
Alexander Couzens6c47f292018-05-22 17:09:49 +02001882
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001883/* Attempt an attach, but loose the Identification Request (IMEI) */
1884private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
1885 var integer count_req := 0;
1886 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1887
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001888 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001889
1890 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001891 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001892 /* break */
1893 }
Harald Welte955aa942019-05-03 01:29:29 +02001894 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001895 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001896 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001897 repeat;
1898 }
Harald Welte955aa942019-05-03 01:29:29 +02001899 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001900 /* ignore ID REQ IMEI */
1901 count_req := count_req + 1;
1902 repeat;
1903 }
1904 }
1905 if (count_req != 5) {
1906 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001907 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02001908 }
1909 setverdict(pass);
1910}
1911
1912testcase TC_attach_no_imei_response() runs on test_CT {
1913 /* MS -> SGSN: Attach Request IMSI
1914 * MS <- SGSN: Identity Request IMSI (optional)
1915 * MS -> SGSN: Identity Response IMSI (optional)
1916 * MS <- SGSN: Identity Request IMEI
1917 * MS -x SGSN: no response
1918 * MS <- SGSN: re-send: Identity Request IMEI 4x
1919 * MS <- SGSN: Attach Reject
1920 */
1921 var BSSGP_ConnHdlr vc_conn;
1922 f_init();
1923 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001924 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 +02001925 vc_conn.done;
1926}
1927
Alexander Couzens53f20562018-06-12 16:24:12 +02001928/* Attempt an attach, but loose the Identification Request (IMSI) */
1929private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
1930 var integer count_req := 0;
1931 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
1932
1933 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
1934 g_pars.p_tmsi := 'c0000035'O;
1935
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001936 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02001937
1938 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001939 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001940 /* break */
1941 }
Harald Welte955aa942019-05-03 01:29:29 +02001942 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001943 /* ignore ID REQ IMSI */
1944 count_req := count_req + 1;
1945 repeat;
1946 }
Harald Welte955aa942019-05-03 01:29:29 +02001947 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02001948 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzenscdfb7512018-07-31 15:37:14 +02001949 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02001950 repeat;
1951 }
1952 }
1953 if (count_req != 5) {
1954 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02001955 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02001956 }
1957 setverdict(pass);
1958}
1959
1960testcase TC_attach_no_imsi_response() runs on test_CT {
1961 /* MS -> SGSN: Attach Request TMSI (unknown)
1962 * MS <- SGSN: Identity Request IMEI (optional)
1963 * MS -> SGSN: Identity Response IMEI (optional)
1964 * MS <- SGSN: Identity Request IMSI
1965 * MS -x SGSN: no response
1966 * MS <- SGSN: re-send: Identity Request IMSI 4x
1967 * MS <- SGSN: Attach Reject
1968 */
1969 var BSSGP_ConnHdlr vc_conn;
1970 f_init();
1971 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001972 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 +02001973 vc_conn.done;
1974}
1975
Alexander Couzenscf818962018-06-05 18:00:00 +02001976private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
1977 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
1978}
1979
1980testcase TC_attach_check_subscriber_list() runs on test_CT {
1981 /* MS <-> SGSN: Attach
1982 * VTY -> SGSN: Check if MS is in subscriber cache
1983 */
1984 var BSSGP_ConnHdlr vc_conn;
1985 var integer id := 34;
1986 var charstring imsi := hex2str(f_gen_imsi(id));
1987
1988 f_init();
1989 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001990 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02001991 vc_conn.done;
1992
1993 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
1994 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
1995}
1996
Alexander Couzensf9858652018-06-07 16:14:53 +02001997private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
1998 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02001999 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002000
2001 /* unregister the old IMSI */
2002 f_bssgp_client_unregister(g_pars.imsi);
2003 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002004 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002005 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002006
2007 /* there is no auth */
2008 g_pars.net.expect_auth := false;
2009
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002010 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002011 f_gmm_auth();
2012 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002013 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002014 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002015 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002016 }
Harald Welte955aa942019-05-03 01:29:29 +02002017 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2018 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002019 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002020 setverdict(pass);
2021 }
2022 }
2023}
Alexander Couzens03d12242018-08-07 16:13:52 +02002024
2025private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2026
2027 f_TC_attach_closed_foreign(id);
2028 f_TC_attach_closed_imsi_added(id);
2029
2030}
2031
2032
Alexander Couzensf9858652018-06-07 16:14:53 +02002033testcase TC_attach_closed_add_vty() runs on test_CT {
2034 /* VTY-> SGSN: policy close
2035 * MS -> SGSN: Attach Request
2036 * MS <- SGSN: Identity Request IMSI
2037 * MS -> SGSN: Identity Response IMSI
2038 * MS <- SGSN: Attach Reject
2039 * VTY-> SGSN: policy imsi-acl add IMSI
2040 * MS -> SGSN: Attach Request
2041 * MS <- SGSN: Identity Request IMSI
2042 * MS -> SGSN: Identity Response IMSI
2043 * MS <- SGSN: Identity Request IMEI
2044 * MS -> SGSN: Identity Response IMEI
2045 * MS <- SGSN: Attach Accept
2046 */
2047 var BSSGP_ConnHdlr vc_conn;
2048 f_init();
2049 f_sleep(1.0);
2050 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2051 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002052 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2053 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002054 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002055 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002056 vc_conn.done;
2057}
2058
Alexander Couzens0085bd72018-06-12 19:08:44 +02002059/* Attempt an attach, but never answer a Attach Complete */
2060private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2061 var integer count_req := 0;
2062
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002063 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02002064 f_gmm_auth();
2065
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002066 timer T := 10.0;
2067 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002068 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002069 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002070 /* break */
2071 }
Harald Welte955aa942019-05-03 01:29:29 +02002072 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002073 /* ignore */
2074 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002075 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002076 repeat;
2077 }
2078 }
2079 if (count_req != 5) {
2080 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002081 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002082 }
2083 setverdict(pass);
2084}
2085
2086testcase TC_attach_check_complete_resend() runs on test_CT {
2087 /* MS -> SGSN: Attach Request IMSI
2088 * MS <- SGSN: Identity Request *
2089 * MS -> SGSN: Identity Response *
2090 * MS <- SGSN: Attach Complete 5x
2091 */
2092 var BSSGP_ConnHdlr vc_conn;
2093 f_init();
2094 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002095 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 +02002096 vc_conn.done;
2097}
2098
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002099private function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002100 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002101
2102 /* then send RAU */
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002103 f_send_l3_gmm_llc(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002104 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002105 [] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2106 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzenscdfb7512018-07-31 15:37:14 +02002107 f_send_l3_gmm_llc(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002108 setverdict(pass);
2109 }
Harald Welte955aa942019-05-03 01:29:29 +02002110 [] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002111 setverdict(fail, "Unexpected RAU Reject");
2112 mtc.stop;
2113 }
2114 [] BSSGP[bssgp].receive { repeat; }
2115 }
2116}
2117
Alexander Couzensbfda9212018-07-31 03:17:33 +02002118private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002119 /* first perform regular attach */
2120 f_TC_attach(id);
2121
2122 /* then send RAU */
2123 f_routing_area_update(g_pars.ra);
2124
2125 /* do another RAU */
2126 f_routing_area_update(g_pars.ra);
2127
2128 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2129}
2130
2131testcase TC_attach_rau_a_a() runs on test_CT {
2132 /* MS <-> SGSN: Successful Attach
2133 * MS -> SGSN: Routing Area Update Request
2134 * MS <- SGSN: Routing Area Update Accept
2135 * MS -> SGSN: Routing Area Update Request
2136 * MS <- SGSN: Routing Area Update Accept
2137 * MS -> SGSN: Detach (PowerOff)
2138 */
2139 var BSSGP_ConnHdlr vc_conn;
2140 f_init();
2141 f_sleep(1.0);
2142 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2143 vc_conn.done;
2144}
2145
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002146private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002147 f_TC_attach(id);
2148
2149 log("attach complete sending rau");
2150 f_routing_area_update(g_pars.ra, 0);
2151
2152 log("rau complete unregistering");
2153 f_bssgp_client_unregister(g_pars.imsi);
2154 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2155
2156 log("sending second RAU via different RA");
2157 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2158
2159 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2160}
2161
2162testcase TC_attach_rau_a_b() runs on test_CT {
2163 /* MS <-> SGSN: Successful Attach
2164 * MS -> SGSN: Routing Area _a_ Update Request
2165 * MS <- SGSN: Routing Area _a_ Update Accept
2166 * MS -> SGSN: Routing Area _b_ Update Request
2167 * MS <- SGSN: Routing Area _b_ Update Accept
2168 * MS -> SGSN: Detach (PowerOff)
2169 */
2170 var BSSGP_ConnHdlr vc_conn;
2171 f_init();
2172 f_sleep(1.0);
2173 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2174 vc_conn.done;
2175}
2176
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002177private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2178 var integer count_req := 0;
2179 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2180 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002181 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002182
2183 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2184
2185 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002186 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002187 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2188 mtc.stop;
2189 }
Harald Welte955aa942019-05-03 01:29:29 +02002190 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002191 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2192 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2193 repeat;
2194 }
Harald Welte955aa942019-05-03 01:29:29 +02002195 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002196 /* send out a second GMM_Attach Request.
2197 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2198 * of the same content */
2199 f_send_l3_gmm_llc(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
2200 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
2201 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2202 }
2203 }
2204 f_sleep(1.0);
2205
2206 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2207 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002208 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002209 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
2210 f_send_l3_gmm_llc(ts_GMM_ID_RESP(mi));
2211 repeat;
2212 }
Harald Welte955aa942019-05-03 01:29:29 +02002213 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002214 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2215 mtc.stop;
2216 }
Harald Welte955aa942019-05-03 01:29:29 +02002217 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002218 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2219 mtc.stop;
2220 }
Harald Welte955aa942019-05-03 01:29:29 +02002221 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2222 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002223 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2224 setverdict(pass);
2225 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2226 }
2227 }
2228}
2229
2230testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2231 /* Testing if the SGSN ignore Attach Request with the exact same content */
2232 /* MS -> SGSN: Attach Request IMSI
2233 * MS <- SGSN: Identity Request IMSI (optional)
2234 * MS -> SGSN: Identity Response IMSI (optional)
2235 * MS <- SGSN: Identity Request IMEI
2236 * MS -> SGSN: Attach Request (2nd)
2237 * MS <- SGSN: Identity Response IMEI
2238 * MS <- SGSN: Attach Accept
2239 * MS -> SGSN: Attach Complete
2240 */
2241 var BSSGP_ConnHdlr vc_conn;
2242 f_init();
2243 f_sleep(1.0);
2244 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2245 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2246 vc_conn.done;
2247}
2248
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002249private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002250 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2251
2252 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2253
2254 /* send Attach Request */
2255 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2256 * 3G auth vectors */
2257 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2258 /* The thing is, if the solSACapability is 'omit', then the
2259 * revisionLevelIndicatior is at the wrong place! */
2260 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
2261 f_send_l3_gmm_llc(attach_req);
2262
2263 /* do the auth */
2264 var PDU_L3_MS_SGSN l3_mo;
2265 var PDU_L3_SGSN_MS l3_mt;
2266 var default di := activate(as_mm_identity());
2267
2268 var GSUP_IE auth_tuple;
2269 var template AuthenticationParameterAUTNTLV autn;
2270
2271 g_pars.vec := f_gen_auth_vec_3g();
2272 autn := {
2273 elementIdentifier := '28'O,
2274 lengthIndicator := lengthof(g_pars.vec.autn),
2275 autnValue := g_pars.vec.autn
2276 };
2277 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2278 g_pars.vec.sres,
2279 g_pars.vec.kc,
2280 g_pars.vec.ik,
2281 g_pars.vec.ck,
2282 g_pars.vec.autn,
2283 g_pars.vec.res));
2284 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2285 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2286 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2287
2288 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2289 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002290 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002291
2292 /* send the gmm auth failure with resync IE */
2293 f_send_l3_gmm_llc(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
2294
2295 /* wait for the GSUP resync request */
2296 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2297 g_pars.imsi,
2298 g_pars.vec.auts,
2299 g_pars.vec.rand));
2300
2301 /* generate new key material */
2302 g_pars.vec := f_gen_auth_vec_3g();
2303 autn := {
2304 elementIdentifier := '28'O,
2305 lengthIndicator := lengthof(g_pars.vec.autn),
2306 autnValue := g_pars.vec.autn
2307 };
2308
2309 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2310 g_pars.vec.sres,
2311 g_pars.vec.kc,
2312 g_pars.vec.ik,
2313 g_pars.vec.ck,
2314 g_pars.vec.autn,
2315 g_pars.vec.res));
2316 /* send new key material */
2317 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2318
2319 /* wait for the new Auth Request */
2320 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2321 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002322 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002323 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2324 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2325 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2326 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2327 valueField := substr(g_pars.vec.res, 0, 4)
2328 };
2329 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2330 elementIdentifier := '21'O,
2331 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2332 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2333 };
2334 l3_mo := valueof(auth_ciph_resp);
2335 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2336 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2337 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2338 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2339 }
2340 f_send_l3_gmm_llc(l3_mo);
2341 deactivate(di);
2342
2343 /* Expect SGSN to perform LU with HLR */
2344 f_gmm_gsup_lu_isd();
2345
Harald Welte955aa942019-05-03 01:29:29 +02002346 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2347 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002348 }
2349 f_send_l3_gmm_llc(ts_GMM_ATTACH_COMPL);
2350 setverdict(pass);
2351}
2352
2353testcase TC_attach_usim_resync() runs on test_CT {
2354 /* MS -> SGSN: Attach Request
2355 * MS <- SGSN: Identity Request IMSI
2356 * MS -> SGSN: Identity Response IMSI
2357 * MS <- SGSN: Identity Request IMEI
2358 * MS -> SGSN: Identity Response IMEI
2359 * HLR<- SGSN: SAI Request
2360 * HLR-> SGSN: SAI Response
2361 * MS <- SGSN: Auth Request
2362 * MS -> SGSN: Auth Failure (with AUTS)
2363 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2364 * HLR-> SGSN: SAI Response (new key material)
2365 * MS <- SGSN: Auth Request (new key material)
2366 * MS -> SGSN: Auth Response
2367 * MS <- SGSN: Attach Accept
2368 * MS -> SGSN: Attach Complete
2369 */
2370 var BSSGP_ConnHdlr vc_conn;
2371 f_init();
2372 f_sleep(1.0);
2373 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2374 vc_conn.done;
2375}
2376
Harald Weltea05b8072019-04-23 22:35:05 +02002377
2378/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2379private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2380 f_gmm_attach(false, false);
2381 f_sleep(1.0);
2382 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2383 /* try to detach to check if SGSN is still alive */
2384 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2385}
2386testcase TC_llc_null() runs on test_CT {
2387 var BSSGP_ConnHdlr vc_conn;
2388 f_init();
2389 f_sleep(1.0);
2390 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2391 vc_conn.done;
2392}
2393
Harald Welte645a1512019-04-23 23:18:23 +02002394/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2395private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2396 f_gmm_attach(false, false);
2397 f_sleep(1.0);
2398 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002399 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002400 setverdict(pass);
2401}
2402testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2403 var BSSGP_ConnHdlr vc_conn;
2404 f_init();
2405 f_sleep(1.0);
2406 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2407 vc_conn.done;
2408}
2409
2410/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2411private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2412 f_gmm_attach(false, false);
2413 f_sleep(1.0);
2414 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002415 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002416 setverdict(pass);
2417}
2418testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2419 var BSSGP_ConnHdlr vc_conn;
2420 f_init();
2421 f_sleep(1.0);
2422 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2423 vc_conn.done;
2424}
2425
Harald Welte2aaac1b2019-05-02 10:02:53 +02002426/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2427private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2428 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2429 var template (value) XID_Information xid;
2430 var template XID_Information xid_rx;
2431
2432 /* first perform regular attach */
2433 f_TC_attach(id);
2434 /* then activate PDP context */
2435 f_pdp_ctx_act(apars);
2436
2437 /* start MO XID */
2438 xid := { ts_XID_L3(''O) };
2439 xid_rx := { tr_XID_L3(''O) };
2440 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2441 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002442 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002443 [] as_xid(apars);
2444 }
2445 setverdict(pass);
2446}
2447testcase TC_xid_empty_l3() runs on test_CT {
2448 var BSSGP_ConnHdlr vc_conn;
2449 f_init();
2450 f_sleep(1.0);
2451 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2452 vc_conn.done;
2453}
2454
2455private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2456 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2457 var template (value) XID_Information xid;
2458 var template XID_Information xid_rx;
2459
2460 /* first perform regular attach */
2461 f_TC_attach(id);
2462 /* then activate PDP context */
2463 f_pdp_ctx_act(apars);
2464
2465 /* start MO XID */
2466 xid := { ts_XID_N201U(1234) };
2467 xid_rx := { tr_XID_N201U(1234) };
2468 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2469 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002470 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002471 [] as_xid(apars);
2472 }
2473 setverdict(pass);
2474}
2475testcase TC_xid_n201u() runs on test_CT {
2476 var BSSGP_ConnHdlr vc_conn;
2477 f_init();
2478 f_sleep(1.0);
2479 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2480 vc_conn.done;
2481}
2482
Alexander Couzens6bee0872019-05-11 01:48:50 +02002483private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2484 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2485
2486 /* first perform regular attach */
2487 f_TC_attach(id);
2488 /* then activate PDP context */
2489 f_pdp_ctx_act(apars);
2490 /* do a normal detach */
2491 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2492}
2493
2494testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2495 /* MS -> SGSN: Attach Request
2496 * MS <-> SGSN: [..]
2497 * MS -> SGSN: Attach Complete
2498 * MS -> SGSN: PDP Activate Request
2499 * MS <- SGSN: PDP Activate Accept
2500 * MS -> SGSN: GMM Detach Request
2501 * MS <- SGSN: GMM Detach Accept
2502 */
2503 var BSSGP_ConnHdlr vc_conn;
2504 f_init();
2505 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2506 vc_conn.done;
2507}
Harald Welte645a1512019-04-23 23:18:23 +02002508
2509
Harald Welte5ac31492018-02-15 20:39:13 +01002510control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002511 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002512 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002513 execute( TC_attach_umts_aka_umts_res() );
2514 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002515 execute( TC_attach_auth_id_timeout() );
2516 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002517 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002518 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002519 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002520 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002521 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002522 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002523 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002524 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002525 execute( TC_attach_closed_add_vty(), 20.0 );
2526 execute( TC_attach_check_subscriber_list(), 20.0 );
2527 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002528 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002529 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2530 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2531 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2532 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002533 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002534 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002535 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002536 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002537 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002538 execute( TC_detach_unknown_nopoweroff() );
2539 execute( TC_detach_unknown_poweroff() );
2540 execute( TC_detach_nopoweroff() );
2541 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002542 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002543 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002544 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002545 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002546 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002547 execute( TC_attach_pdp_act_user_deact_mt() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002548 execute( TC_attach_second_attempt() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002549 execute( TC_attach_restart_ctr_echo() );
2550 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002551 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002552 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2553 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002554 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002555 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002556 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002557
Harald Welte2aaac1b2019-05-02 10:02:53 +02002558 execute( TC_xid_empty_l3() );
2559 execute( TC_xid_n201u() );
2560
Harald Weltea05b8072019-04-23 22:35:05 +02002561 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002562 execute( TC_llc_sabm_dm_llgmm() );
2563 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002564}
Harald Welte96a33b02018-02-04 10:36:22 +01002565
2566
2567
2568}