blob: 182cbd2c46a24dc54999c85ef26f338ca5ce97e5 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010018import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010019import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010023import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020024import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010025
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from GSUP_Emulation all;
33import from GSUP_Types all;
34import from IPA_Emulation all;
35
Harald Welte26fbb6e2019-04-14 17:32:46 +020036import from RAN_Adapter all;
37import from RAN_Emulation all;
38import from RANAP_Templates all;
39import from RANAP_PDU_Descriptions all;
40import from RANAP_IEs all;
41
Harald Welteeded9ad2018-02-17 20:57:34 +010042import from GTP_Emulation all;
43import from GTP_Templates all;
44import from GTP_CodecPort all;
45import from GTPC_Types all;
46import from GTPU_Types all;
47
Harald Weltea2526a82018-02-18 19:03:36 +010048import from LLC_Types all;
49import from LLC_Templates all;
50
51import from SNDCP_Types all;
52
Harald Weltebd194722018-02-16 22:11:08 +010053import from TELNETasp_PortType all;
54import from Osmocom_VTY_Functions all;
55
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010056import from GSM_RR_Types all;
57
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020058import from MobileL3_MM_Types all;
59
Harald Welteeded9ad2018-02-17 20:57:34 +010060
Harald Welte5ac31492018-02-15 20:39:13 +010061modulepar {
62 /* IP/port on which we run our internal GSUP/HLR emulation */
63 charstring mp_hlr_ip := "127.0.0.1";
64 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010065 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020066 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020067
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 NSConfigurations mp_nsconfig := {
69 {
70 local_udp_port := 21010,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 96,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21011,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 97,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 },
89 {
90 local_udp_port := 21012,
91 local_ip := "127.0.0.1",
92 remote_udp_port := 23000,
93 remote_ip := "127.0.0.1",
94 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020095 nsei := 98,
96 role_sgsn := false,
97 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020098 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020099 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200100
101 RAN_Configurations mp_ranap_cfg := {
102 {
103 transport := RANAP_TRANSPORT_IuCS,
104 sccp_service_type := "mtp3_itu",
105 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
106 own_pc := 195,
107 own_ssn := 142,
108 peer_pc := 188, /* 0.23.4 */
109 peer_ssn := 142,
110 sio := '83'O,
111 rctx := 2
112 }
113 }
Harald Welte5ac31492018-02-15 20:39:13 +0100114};
115
116type record GbInstance {
117 NS_CT vc_NS,
118 BSSGP_CT vc_BSSGP,
119 BssgpConfig cfg
120};
Harald Welte96a33b02018-02-04 10:36:22 +0100121
Harald Welte2fa771f2019-05-02 20:13:53 +0200122const integer NUM_GB := 3;
123type record length(NUM_GB) of GbInstance GbInstances;
124type record length(NUM_GB) of NSConfiguration NSConfigurations;
125type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200126
Harald Welte26fbb6e2019-04-14 17:32:46 +0200127const integer NUM_RNC := 1;
128type record of RAN_Configuration RAN_Configurations;
129
Harald Welte96a33b02018-02-04 10:36:22 +0100130type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200131 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200132 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200133 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100134
Harald Welte5ac31492018-02-15 20:39:13 +0100135 var GSUP_Emulation_CT vc_GSUP;
136 var IPA_Emulation_CT vc_GSUP_IPA;
137 /* only to get events from IPA underneath GSUP */
138 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100139
Harald Welteeded9ad2018-02-17 20:57:34 +0100140 var GTP_Emulation_CT vc_GTP;
141
Harald Weltebd194722018-02-16 22:11:08 +0100142 port TELNETasp_PT SGSNVTY;
143
Harald Welte96a33b02018-02-04 10:36:22 +0100144 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200145 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100146};
147
Harald Welte26fbb6e2019-04-14 17:32:46 +0200148type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100149 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100150 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200151 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100152}
153
154type record SGSN_ConnHdlrNetworkPars {
155 boolean expect_ptmsi,
156 boolean expect_auth,
157 boolean expect_ciph
158};
159
160type record BSSGP_ConnHdlrPars {
161 /* IMEI of the simulated ME */
162 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200163 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100164 hexstring imsi,
165 /* MSISDN of the simulated MS (probably unused) */
166 hexstring msisdn,
167 /* P-TMSI allocated to the simulated MS */
168 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100169 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100170 /* TLLI of the simulated MS */
171 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100172 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100173 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200174 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200175 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
176 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100177 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100178 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200179 float t_guard,
180 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200181 SCCP_PAR_Address sccp_addr_local optional,
182 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100183};
184
Alexander Couzens89508702018-07-31 04:16:10 +0200185private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200186 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200187 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
188
189 var RoutingAreaIdentificationV ret := {
190 mccDigit1 := mcc_mnc[0],
191 mccDigit2 := mcc_mnc[1],
192 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200193 mncDigit3 := mcc_mnc[3],
194 mncDigit1 := mcc_mnc[4],
195 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200196 lac := int2oct(cell_id.ra_id.lai.lac, 16),
197 rac := int2oct(cell_id.ra_id.rac, 8)
198 }
199 return ret;
200};
201
Alexander Couzens51114d12018-07-31 18:41:56 +0200202private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
203 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
204 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100205 /* connect lower end of BSSGP emulation with NS upper port */
206 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
207 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
208 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
209
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200210 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100211 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
212}
213
214private function f_init_gsup(charstring id) runs on test_CT {
215 id := id & "-GSUP";
216 var GsupOps ops := {
217 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
218 };
219
220 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
221 vc_GSUP := GSUP_Emulation_CT.create(id);
222
223 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
224 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
225 /* we use this hack to get events like ASP_IPA_EVENT_UP */
226 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
227
228 vc_GSUP.start(GSUP_Emulation.main(ops, id));
229 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
230
231 /* wait for incoming connection to GSUP port before proceeding */
232 timer T := 10.0;
233 T.start;
234 alt {
235 [] GSUP_IPA_EVENT.receive(t_ASP_IPA_EVT_UD(ASP_IPA_EVENT_UP)) { }
236 [] T.timeout {
237 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200238 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100239 }
240 }
241}
242
Harald Welteeded9ad2018-02-17 20:57:34 +0100243private function f_init_gtp(charstring id) runs on test_CT {
244 id := id & "-GTP";
245
246 var GtpEmulationCfg gtp_cfg := {
247 gtpc_bind_ip := mp_ggsn_ip,
248 gtpc_bind_port := GTP1C_PORT,
249 gtpu_bind_ip := mp_ggsn_ip,
250 gtpu_bind_port := GTP1U_PORT,
251 sgsn_role := false
252 };
253
254 vc_GTP := GTP_Emulation_CT.create(id);
255 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
256}
257
Harald Weltebd194722018-02-16 22:11:08 +0100258private function f_init_vty() runs on test_CT {
259 map(self:SGSNVTY, system:SGSNVTY);
260 f_vty_set_prompts(SGSNVTY);
261 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200262 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100263 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
264}
265
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200266private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
267 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200268 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200269 } else {
270 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
271 }
272}
273
Harald Weltebd194722018-02-16 22:11:08 +0100274
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200275/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
276function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200277 var integer i;
278
Harald Welte96a33b02018-02-04 10:36:22 +0100279 if (g_initialized == true) {
280 return;
281 }
282 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100283 g_gb[0].cfg := {
284 nsei := 96,
285 bvci := 196,
286 cell_id := {
287 ra_id := {
288 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100289 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100290 rac := 0
291 },
292 cell_id := 20960
293 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200294 sgsn_role := false,
295 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100296 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200297 g_gb[1].cfg := {
298 nsei := 97,
299 bvci := 210,
300 cell_id := {
301 ra_id := {
302 lai := {
303 mcc_mnc := mcc_mnc, lac := 13200},
304 rac := 0
305 },
306 cell_id := 20961
307 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200308 sgsn_role := false,
309 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200310 };
311 g_gb[2].cfg := {
312 nsei := 98,
313 bvci := 220,
314 cell_id := {
315 ra_id := {
316 lai := {
317 mcc_mnc := mcc_mnc, lac := 13300},
318 rac := 0
319 },
320 cell_id := 20962
321 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200322 sgsn_role := false,
323 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200324 };
Harald Welte96a33b02018-02-04 10:36:22 +0100325
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200326 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200327 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
328 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
329 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200330
Alexander Couzens1552e792019-07-23 20:38:39 +0200331 if (g_ranap_enable) {
332 for (i := 0; i < NUM_RNC; i := i+1) {
333 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
334 f_ran_adapter_start(g_ranap[i]);
335 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200336 }
Harald Welte5ac31492018-02-15 20:39:13 +0100337 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100338 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200339 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100340}
Harald Welte96a33b02018-02-04 10:36:22 +0100341
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200342function f_cleanup() runs on test_CT {
343 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200344 if (g_ranap_enable) {
345 for (i := 0; i < NUM_RNC; i := i+1) {
346 f_ran_adapter_cleanup(g_ranap[i]);
347 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200348 }
349 self.stop;
350}
351
Harald Welte26fbb6e2019-04-14 17:32:46 +0200352private function RncUnitdataCallback(RANAP_PDU ranap)
353runs on RAN_Emulation_CT return template RANAP_PDU {
354 var template RANAP_PDU resp := omit;
355
356 log ("RANAP_RncUnitDataCallback");
357 /* answer all RESET with RESET ACK */
358 if (match(ranap, tr_RANAP_Reset)) {
359 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
360 var CN_DomainIndicator dom;
361 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
362 resp := ts_RANAP_ResetAck(dom);
363 }
364 return resp;
365}
366
367const RanOps RNC_RanOps := {
368 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
369 ranap_unitdata_cb := refers(RncUnitdataCallback),
370 ps_domain := true,
371 decode_dtap := true,
372 role_ms := true,
373 protocol := RAN_PROTOCOL_RANAP,
374 transport := RANAP_TRANSPORT_IuCS,
375 use_osmux := false,
376 sccp_addr_local := omit,
377 sccp_addr_peer := omit
378};
379
Harald Welte5ac31492018-02-15 20:39:13 +0100380type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
381
382/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200383function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100384 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100385runs on test_CT return BSSGP_ConnHdlr {
386 var BSSGP_ConnHdlr vc_conn;
387 var SGSN_ConnHdlrNetworkPars net_pars := {
388 expect_ptmsi := true,
389 expect_auth := true,
390 expect_ciph := false
391 };
392 var BSSGP_ConnHdlrPars pars := {
393 imei := f_gen_imei(imsi_suffix),
394 imsi := f_gen_imsi(imsi_suffix),
395 msisdn := f_gen_msisdn(imsi_suffix),
396 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100397 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100398 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100399 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100400 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200401 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200402 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100403 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100404 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200405 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200406 sccp_addr_local := omit,
407 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100408 };
409
Alexander Couzens1552e792019-07-23 20:38:39 +0200410 if (g_ranap_enable) {
411 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
412 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
413 }
414
Harald Welte5ac31492018-02-15 20:39:13 +0100415 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200416 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
417 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
418 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
419 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
420 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
421 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100422
Harald Welte26fbb6e2019-04-14 17:32:46 +0200423 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200424 if (g_ranap_enable) {
425 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
426 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
427 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200428
Harald Welte5ac31492018-02-15 20:39:13 +0100429 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
430 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
431
Harald Welteeded9ad2018-02-17 20:57:34 +0100432 connect(vc_conn:GTP, vc_GTP:CLIENT);
433 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
434
Harald Welte5ac31492018-02-15 20:39:13 +0100435 vc_conn.start(f_handler_init(fn, id, pars));
436 return vc_conn;
437}
438
Harald Welte62e29582018-02-16 21:17:11 +0100439private altstep as_Tguard() runs on BSSGP_ConnHdlr {
440 [] g_Tguard.timeout {
441 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200442 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100443 }
444}
445
Harald Welte5ac31492018-02-15 20:39:13 +0100446/* first function called in every ConnHdlr */
447private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
448runs on BSSGP_ConnHdlr {
449 /* do some common stuff like setting up g_pars */
450 g_pars := pars;
451
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200452 llc := f_llc_create(false);
453
Harald Welte5ac31492018-02-15 20:39:13 +0100454 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200455 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100456 /* tell GSUP dispatcher to send this IMSI to us */
457 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100458 /* tell GTP dispatcher to send this IMSI to us */
459 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100460
Harald Welte62e29582018-02-16 21:17:11 +0100461 g_Tguard.start(pars.t_guard);
462 activate(as_Tguard());
463
Harald Welte5ac31492018-02-15 20:39:13 +0100464 /* call the user-supplied test case function */
465 fn.apply(id);
466 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100467}
468
469/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100470 * Detach without Attach
471 * SM procedures without attach / RAU
472 * ATTACH / RAU
473 ** with / without authentication
474 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100475 * re-transmissions of LLC frames
476 * PDP Context activation
477 ** with different GGSN config in SGSN VTY
478 ** with different PDP context type (v4/v6/v46)
479 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100480 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100481 */
482
483testcase TC_wait_ns_up() runs on test_CT {
484 f_init();
485 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200486 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100487}
488
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200489friend function is_gb(integer gb_idx) return boolean {
490 return gb_idx < NUM_GB;
491}
492friend function is_iu(integer gb_idx) return boolean {
493 return gb_idx >= NUM_GB;
494}
495
Harald Weltea05b8072019-04-23 22:35:05 +0200496function f_send_llc(template (value) PDU_LLC llc_pdu, integer gb_index := 0) runs on BSSGP_ConnHdlr {
497 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
498 BSSGP[gb_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[gb_index], llc_enc));
499}
500
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200501private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200502 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
503 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
504 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzensad352222019-05-11 02:06:04 +0200505 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), gb_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200506}
507
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200508/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
509function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
510 log("Sending InitialUE: ", l3_mo);
511 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
512 var RANAP_PDU ranap;
513 var LAI lai := {
514 pLMNidentity := '62F224'O,
515 lAC := '1234'O,
516 iE_Extensions := omit
517 };
518 var SAI sai := {
519 pLMNidentity := lai.pLMNidentity,
520 lAC := lai.lAC,
521 sAC := '0000'O, /* FIXME */
522 iE_Extensions := omit
523 };
524 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
525 var GlobalRNC_ID grnc_id := {
526 pLMNidentity := lai.pLMNidentity,
527 rNC_ID := 2342 /* FIXME */
528 };
529
530 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
531 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
532 alt {
533 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
534 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
535 setverdict(fail, "DISC.ind from SCCP");
536 mtc.stop;
537 }
538 }
539}
540
541/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
542function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer gb_index := 0) runs on BSSGP_ConnHdlr {
543 if (is_iu(gb_index)) {
544 if (g_pars.rnc_send_initial_ue) {
545 g_pars.rnc_send_initial_ue := false;
546 f_send_l3_initial_ue(l3_mo);
547 } else {
548 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
549 }
550 } else {
551 f_send_l3_gmm_llc(l3_mo, gb_index);
552 }
553}
554
Harald Welteca362462019-05-02 20:11:21 +0200555altstep as_mm_identity(integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100556 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200557 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100558 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200559 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100560 repeat;
561 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200562 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
563 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
564 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
565 repeat;
566 }
567 [is_gb(gb_idx)] BSSGP[gb_idx].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100568 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200569 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
570 repeat;
571 }
572 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
573 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
574 f_send_l3(ts_GMM_ID_RESP(mi), gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100575 repeat;
576 }
577}
Harald Welte96a33b02018-02-04 10:36:22 +0100578
Harald Welteca362462019-05-02 20:11:21 +0200579/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
580function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer gb_idx := 0)
581runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200582 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200583 var PDU_L3_SGSN_MS l3_mt;
584 alt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200585 [is_gb(gb_idx)] BSSGP[gb_idx].receive(rx_tpl) -> value l3_mt { }
586 [is_iu(gb_idx)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
587 l3_mt := mt.dtap;
588 }
Harald Welteca362462019-05-02 20:11:21 +0200589 }
590 return l3_mt;
591}
592
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200593/* perform GMM authentication (if expected).
594 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
595 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Harald Welteca362462019-05-02 20:11:21 +0200596function 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 +0100597 var PDU_L3_MS_SGSN l3_mo;
598 var PDU_L3_SGSN_MS l3_mt;
Harald Welteca362462019-05-02 20:11:21 +0200599 var default di := activate(as_mm_identity(gb_idx));
Harald Welte5ac31492018-02-15 20:39:13 +0100600 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200601 var GSUP_IE auth_tuple;
602 var template AuthenticationParameterAUTNTLV autn;
603
604 if (umts_aka_challenge) {
605 g_pars.vec := f_gen_auth_vec_3g();
606 autn := {
607 elementIdentifier := '28'O,
608 lengthIndicator := lengthof(g_pars.vec.autn),
609 autnValue := g_pars.vec.autn
610 };
611
612 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
613 g_pars.vec.sres,
614 g_pars.vec.kc,
615 g_pars.vec.ik,
616 g_pars.vec.ck,
617 g_pars.vec.autn,
618 g_pars.vec.res));
619 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
620 } else {
621 g_pars.vec := f_gen_auth_vec_2g();
622 autn := omit;
623 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
624 g_pars.vec.sres,
625 g_pars.vec.kc));
626 log("GSUP sends only 2G auth tuple", auth_tuple);
627 }
Harald Welteca362462019-05-02 20:11:21 +0200628
Harald Welte5ac31492018-02-15 20:39:13 +0100629 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
630 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200631
632 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
633 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welteca362462019-05-02 20:11:21 +0200634 l3_mt := f_receive_l3(auth_ciph_req, gb_idx);
Harald Welte5ac31492018-02-15 20:39:13 +0100635 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200636 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
637
638 if (umts_aka_challenge and not force_gsm_sres) {
639 /* set UMTS response instead */
640 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
641 valueField := substr(g_pars.vec.res, 0, 4)
642 };
643 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
644 elementIdentifier := '21'O,
645 lengthIndicator := lengthof(g_pars.vec.res) - 4,
646 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
647 };
648 }
649
650 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100651 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
652 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
653 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
654 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
655 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200656 f_send_l3(l3_mo, gb_idx);
657
658 /* Security Mode Command + Complete on Iu case */
659 if (is_iu(gb_idx)) {
660 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
661 key_sts := ?)) {
662 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
663 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
664 }
665 }
Harald Welte76dee092018-02-16 22:12:59 +0100666 } else {
667 /* wait for identity procedure */
668 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100669 }
Harald Welte76dee092018-02-16 22:12:59 +0100670
Harald Welte5ac31492018-02-15 20:39:13 +0100671 deactivate(di);
672}
673
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200674function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100675 g_pars.p_tmsi := p_tmsi;
676 /* update TLLI */
677 g_pars.tlli_old := g_pars.tlli;
678 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200679 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[bssgp_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100680}
681
Harald Welte04683d02018-02-16 22:43:45 +0100682function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
683 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100684 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200685 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100686 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200687 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200688 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100689 }
Harald Welte04683d02018-02-16 22:43:45 +0100690 g_pars.ra := aa.routingAreaIdentification;
691 if (ispresent(aa.allocatedPTMSI)) {
692 if (not g_pars.net.expect_ptmsi) {
693 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200694 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100695 }
Harald Weltef70997d2018-02-17 10:11:19 +0100696 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100697 }
698 if (ispresent(aa.msIdentity)) {
699 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200700 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100701 }
702 /* P-TMSI.sig */
703 if (ispresent(aa.ptmsiSignature)) {
704 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
705 }
706 /* updateTimer */
707 // aa.readyTimer
708 /* T3302, T3319, T3323, T3312_ext, T3324 */
709}
710
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200711function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer bssgp_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100712 /* mandatory IE */
713 g_pars.ra := ra.routingAreaId;
714 if (ispresent(ra.allocatedPTMSI)) {
715 if (not g_pars.net.expect_ptmsi) {
716 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200717 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100718 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +0200719 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, bssgp_index);
Harald Welte91636de2018-02-17 10:16:14 +0100720 }
721 if (ispresent(ra.msIdentity)) {
722 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200723 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100724 }
725 /* P-TMSI.sig */
726 if (ispresent(ra.ptmsiSignature)) {
727 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
728 }
729 /* updateTimer */
730 // aa.readyTimer
731 /* T3302, T3319, T3323, T3312_ext, T3324 */
732}
733
734
Harald Welte5a4fa042018-02-16 20:59:21 +0100735function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
736 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
737}
738
Harald Welte23178c52018-02-17 09:36:33 +0100739/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100740private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100741 if (ispresent(g_pars.p_tmsi)) {
742 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
743 } else {
744 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
745 }
746}
747
Harald Welte311ec272018-02-17 09:40:03 +0100748private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100749 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100750 /* Expect MSC to perform LU with HLR */
751 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100752 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
753 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
754 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100755 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
756 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
757}
758
Harald Welteca362462019-05-02 20:11:21 +0200759friend 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 +0100760 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200761 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 +0200762 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100763
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200764 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
765 * 3G auth vectors */
766 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
767 /* The thing is, if the solSACapability is 'omit', then the
768 * revisionLevelIndicatior is at the wrong place! */
769 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
770
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200771 f_send_l3(attach_req, gb_idx);
Harald Welteca362462019-05-02 20:11:21 +0200772 f_gmm_auth(umts_aka_challenge, force_gsm_sres, gb_idx);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200773 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100774 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100775
Harald Welteca362462019-05-02 20:11:21 +0200776 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), gb_idx);
777 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
778
Harald Welte04683d02018-02-16 22:43:45 +0100779 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200780 f_send_l3(ts_GMM_ATTACH_COMPL, gb_idx);
781
782 /* IuPS case: Expect Iu Release */
783 if (is_iu(gb_idx)) {
784 as_iu_release_compl_disc();
785 }
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200786}
787
788private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
789 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100790 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100791}
792
793testcase TC_attach() runs on test_CT {
794 var BSSGP_ConnHdlr vc_conn;
795 f_init();
796 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200797 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100798 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200799 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100800}
801
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100802testcase TC_attach_mnc3() runs on test_CT {
803 var BSSGP_ConnHdlr vc_conn;
804 f_init('023042'H);
805 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200806 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100807 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200808 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100809}
810
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200811private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
812 f_gmm_attach(true, false);
813 setverdict(pass);
814}
815testcase TC_attach_umts_aka_umts_res() runs on test_CT {
816 var BSSGP_ConnHdlr vc_conn;
817 f_init();
818 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200819 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200820 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200821 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200822}
823
824private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
825 f_gmm_attach(true, true);
826 setverdict(pass);
827}
828testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
829 var BSSGP_ConnHdlr vc_conn;
830 f_init();
831 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200832 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200833 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200834 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200835}
836
Harald Welte5b7c8122018-02-16 21:48:17 +0100837/* MS never responds to ID REQ, expect ATTACH REJECT */
838private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100839 var RoutingAreaIdentificationV old_ra := f_random_RAI();
840
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200841 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100842 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200843 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100844 /* don't send ID Response */
845 repeat;
846 }
Harald Welte955aa942019-05-03 01:29:29 +0200847 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100848 setverdict(pass);
849 }
Harald Welte955aa942019-05-03 01:29:29 +0200850 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100851 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200852 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100853 }
854 }
855}
856testcase TC_attach_auth_id_timeout() runs on test_CT {
857 var BSSGP_ConnHdlr vc_conn;
858 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200859 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 +0100860 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200861 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100862}
863
864/* HLR never responds to SAI REQ, expect ATTACH REJECT */
865private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100866 var RoutingAreaIdentificationV old_ra := f_random_RAI();
867
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200868 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100869 alt {
870 [] as_mm_identity();
871 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
872 }
873 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200874 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100875 setverdict(pass);
876}
877testcase TC_attach_auth_sai_timeout() runs on test_CT {
878 var BSSGP_ConnHdlr vc_conn;
879 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200880 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100881 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200882 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100883}
884
Harald Weltefe253882018-02-17 09:25:00 +0100885/* HLR rejects SAI, expect ATTACH REJECT */
886private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100887 var RoutingAreaIdentificationV old_ra := f_random_RAI();
888
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200889 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100890 alt {
891 [] as_mm_identity();
892 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
893 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
894 }
895 }
Harald Welte955aa942019-05-03 01:29:29 +0200896 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100897 setverdict(pass);
898}
899testcase TC_attach_auth_sai_reject() runs on test_CT {
900 var BSSGP_ConnHdlr vc_conn;
901 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200902 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100903 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200904 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100905}
906
Harald Welte5b7c8122018-02-16 21:48:17 +0100907/* HLR never responds to UL REQ, expect ATTACH REJECT */
908private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200909 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100910 var RoutingAreaIdentificationV old_ra := f_random_RAI();
911
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200912 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100913 f_gmm_auth();
914 /* Expect MSC to perform LU with HLR */
915 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
916 /* Never follow-up with ISD_REQ or UL_RES */
917 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200918 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100919 setverdict(pass);
920 }
Harald Welte955aa942019-05-03 01:29:29 +0200921 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
922 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100923 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200924 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100925 }
926 }
927}
928testcase TC_attach_gsup_lu_timeout() runs on test_CT {
929 var BSSGP_ConnHdlr vc_conn;
930 f_init();
931 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200932 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100933 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200934 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100935}
936
Harald Welteb7c14e92018-02-17 09:29:16 +0100937/* HLR rejects UL REQ, expect ATTACH REJECT */
938private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200939 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100940 var RoutingAreaIdentificationV old_ra := f_random_RAI();
941
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200942 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100943 f_gmm_auth();
944 /* Expect MSC to perform LU with HLR */
945 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
946 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
947 }
948 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200949 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100950 setverdict(pass);
951 }
Harald Welte955aa942019-05-03 01:29:29 +0200952 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
953 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100954 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200955 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100956 }
957 }
958}
959testcase TC_attach_gsup_lu_reject() runs on test_CT {
960 var BSSGP_ConnHdlr vc_conn;
961 f_init();
962 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200963 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100964 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200965 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100966}
967
968
Harald Welte3823e2e2018-02-16 21:53:48 +0100969/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
970private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200971 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100972 var RoutingAreaIdentificationV old_ra := f_random_RAI();
973
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200974 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100975 f_gmm_auth();
976 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100977 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100978
Harald Welte955aa942019-05-03 01:29:29 +0200979 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
980 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100981 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200982 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100983 setverdict(pass);
984}
Harald Welte3823e2e2018-02-16 21:53:48 +0100985testcase TC_attach_combined() runs on test_CT {
986 var BSSGP_ConnHdlr vc_conn;
987 f_init();
988 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200989 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100990 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200991 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +0100992}
993
Harald Welte76dee092018-02-16 22:12:59 +0100994/* Attempt of GPRS ATTACH in 'accept all' mode */
995private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200996 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100997 var RoutingAreaIdentificationV old_ra := f_random_RAI();
998
999 g_pars.net.expect_auth := false;
1000
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001001 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001002 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001003 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1004 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001005 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001006 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001007 setverdict(pass);
1008}
1009testcase TC_attach_accept_all() runs on test_CT {
1010 var BSSGP_ConnHdlr vc_conn;
1011 f_init();
1012 f_sleep(1.0);
1013 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001014 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001015 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001016 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001017}
Harald Welte5b7c8122018-02-16 21:48:17 +01001018
Harald Welteb2124b22018-02-16 22:26:56 +01001019/* Attempt of GPRS ATTACH in 'accept all' mode */
1020private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001021 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1022
1023 /* Simulate a foreign IMSI */
1024 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001025 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001026
1027 g_pars.net.expect_auth := false;
1028
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001029 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001030 alt {
1031 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001032 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001033 setverdict(pass);
1034 }
Harald Welte955aa942019-05-03 01:29:29 +02001035 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001036 setverdict(pass);
1037 }
Harald Welte955aa942019-05-03 01:29:29 +02001038 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001039 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001040 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001041 }
Harald Welteb2124b22018-02-16 22:26:56 +01001042 }
1043}
1044testcase TC_attach_closed() runs on test_CT {
1045 var BSSGP_ConnHdlr vc_conn;
1046 f_init();
1047 f_sleep(1.0);
1048 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1049 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001050 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001051 vc_conn.done;
1052 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001053 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001054 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001055 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001056}
1057
Harald Welte04683d02018-02-16 22:43:45 +01001058/* Routing Area Update from Unknown TLLI -> REJECT */
1059private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001060 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1061
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001062 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, old_ra, false, omit, omit));
Harald Welte04683d02018-02-16 22:43:45 +01001063 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001064 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +01001065 setverdict(pass);
1066 }
1067 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001068 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001069 }
1070}
1071testcase TC_rau_unknown() runs on test_CT {
1072 var BSSGP_ConnHdlr vc_conn;
1073 f_init();
1074 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001075 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001076 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001077 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001078}
1079
Harald Welte91636de2018-02-17 10:16:14 +01001080private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001081 /* first perform regular attach */
1082 f_TC_attach(id);
1083
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001084 f_routing_area_update(g_pars.ra);
1085
Harald Welte91636de2018-02-17 10:16:14 +01001086}
1087testcase TC_attach_rau() runs on test_CT {
1088 var BSSGP_ConnHdlr vc_conn;
1089 f_init();
1090 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001091 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001092 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001093 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001094}
Harald Welte04683d02018-02-16 22:43:45 +01001095
Harald Welte6abb9fe2018-02-17 15:24:48 +01001096/* general GPRS DETACH helper */
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001097function 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 +02001098 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001099 timer T := 5.0;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001100 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), bssgp_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001101 if (expect_purge) {
1102 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1103 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1104 }
1105 T.start;
1106 alt {
1107 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1108 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001109 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001110 }
Harald Welte955aa942019-05-03 01:29:29 +02001111 [power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001112 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001113 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001114 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001115 /* TODO: check if any PDP contexts are deactivated on network side? */
1116 }
1117 [power_off] T.timeout {
1118 setverdict(pass);
1119 }
Harald Welte955aa942019-05-03 01:29:29 +02001120 [not power_off] BSSGP[bssgp_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001121 g_pars.ra := omit;
1122 setverdict(pass);
1123 /* TODO: check if any PDP contexts are deactivated on network side? */
1124 }
Harald Welte955aa942019-05-03 01:29:29 +02001125 [] BSSGP[bssgp_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001126 if (power_off) {
1127 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1128 } else {
1129 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1130 }
1131 mtc.stop;
1132 }
Alexander Couzens90fe6a22018-07-31 19:37:32 +02001133 [] BSSGP[bssgp_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001134 }
1135}
1136
1137/* IMSI DETACH (non-power-off) for unknown TLLI */
1138private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1139 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1140}
1141testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1142 var BSSGP_ConnHdlr vc_conn;
1143 f_init();
1144 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001145 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001146 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001147 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001148}
1149
1150/* IMSI DETACH (power-off) for unknown TLLI */
1151private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1152 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1153}
1154testcase TC_detach_unknown_poweroff() runs on test_CT {
1155 var BSSGP_ConnHdlr vc_conn;
1156 f_init();
1157 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001158 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001159 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001160 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001161}
1162
1163/* IMSI DETACH (non-power-off) for known TLLI */
1164private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1165 /* first perform regular attach */
1166 f_TC_attach(id);
1167
1168 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1169}
1170testcase TC_detach_nopoweroff() runs on test_CT {
1171 var BSSGP_ConnHdlr vc_conn;
1172 f_init();
1173 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001174 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001175 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001176 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001177}
1178
1179/* IMSI DETACH (power-off) for known TLLI */
1180private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1181 /* first perform regular attach */
1182 f_TC_attach(id);
1183
1184 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1185}
1186testcase TC_detach_poweroff() runs on test_CT {
1187 var BSSGP_ConnHdlr vc_conn;
1188 f_init();
1189 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001190 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001191 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001192 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001193}
1194
Harald Welteeded9ad2018-02-17 20:57:34 +01001195type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001196 BIT3 tid, /* L3 Transaction ID */
1197 BIT4 nsapi, /* SNDCP NSAPI */
1198 BIT4 sapi, /* LLC SAPI */
1199 QoSV qos, /* QoS parameters */
1200 PDPAddressV addr, /* IP address */
1201 octetstring apn optional, /* APN name */
1202 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1203 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001204 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001205 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001206
Harald Welte822f9102018-02-18 20:39:06 +01001207 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1208 OCT4 ggsn_tei_u, /* GGSN TEI User */
1209 octetstring ggsn_ip_c, /* GGSN IP Control */
1210 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001211 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001212
Harald Welte822f9102018-02-18 20:39:06 +01001213 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1214 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1215 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1216 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001217};
1218
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001219
1220private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1221 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1222 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1223 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1224 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1225 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1226 f_gtp_register_teid(apars.ggsn_tei_c);
1227 f_gtp_register_teid(apars.ggsn_tei_u);
1228}
1229
Harald Weltef7191672019-05-02 20:37:23 +02001230function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer gb_idx := 0)
1231runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001232 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1233 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001234 var template Recovery_gtpc recovery := omit;
1235
1236 if (send_recovery) {
1237 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1238 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001239
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001240 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Weltef7191672019-05-02 20:37:23 +02001241 apars.apn, apars.pco), gb_idx);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001242 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1243 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1244 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1245 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1246 apars.sgsn_tei_c, apars.gtp_resp_cause,
1247 apars.ggsn_tei_c, apars.ggsn_tei_u,
1248 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001249 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1250 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001251 }
1252 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001253 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001254 setverdict(pass);
1255 }
Harald Welte955aa942019-05-03 01:29:29 +02001256 [exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001257 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001258 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001259 }
Harald Welte955aa942019-05-03 01:29:29 +02001260 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001261 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001262 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001263 }
Harald Welte955aa942019-05-03 01:29:29 +02001264 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001265 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1266 mtc.stop;
1267 }
Harald Welte955aa942019-05-03 01:29:29 +02001268 [not exp_rej] BSSGP[gb_idx].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001269 setverdict(pass);
1270 }
Harald Weltef7191672019-05-02 20:37:23 +02001271 [] as_xid(apars, gb_idx);
Harald Welteeded9ad2018-02-17 20:57:34 +01001272 }
1273}
1274
Harald Weltef7191672019-05-02 20:37:23 +02001275function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer gb_idx := 0)
1276runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001277 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1278 var Gtp1cUnitdata g_ud;
1279
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001280 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001281 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1282 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Harald Weltef7191672019-05-02 20:37:23 +02001283 BSSGP[gb_idx].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001284 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1285 }
1286 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001287 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001288 setverdict(pass);
1289 }
Harald Weltef7191672019-05-02 20:37:23 +02001290 [] as_xid(apars, gb_idx);
Harald Welte6f203162018-02-18 22:04:55 +01001291 }
1292}
1293
Harald Weltef7191672019-05-02 20:37:23 +02001294function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer gb_idx := 0)
1295runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001296 var Gtp1cUnitdata g_ud;
1297 var integer seq_nr := 23;
1298 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1299
Harald Weltef7191672019-05-02 20:37:23 +02001300 BSSGP[gb_idx].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001301 if (error_ind) {
1302 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1303 } else {
1304 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1305 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001306
1307 timer T := 5.0;
1308 T.start;
1309
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001310 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001311 [] BSSGP[gb_idx].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001312 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), gb_idx);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001313 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001314 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1315 repeat;
1316 }
1317 [] T.timeout {
1318 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1319 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001320 }
1321}
1322
Harald Welte6f203162018-02-18 22:04:55 +01001323
Harald Welteeded9ad2018-02-17 20:57:34 +01001324/* Table 10.5.156/3GPP TS 24.008 */
1325template (value) QoSV t_QosDefault := {
1326 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1327 delayClass := '100'B, /* best effort */
1328 spare1 := '00'B,
1329 precedenceClass := '010'B, /* normal */
1330 spare2 := '0'B,
1331 peakThroughput := '0000'B, /* subscribed */
1332 meanThroughput := '00000'B, /* subscribed */
1333 spare3 := '000'B,
1334 deliverErroneusSDU := omit,
1335 deliveryOrder := omit,
1336 trafficClass := omit,
1337 maxSDUSize := omit,
1338 maxBitrateUplink := omit,
1339 maxBitrateDownlink := omit,
1340 sduErrorRatio := omit,
1341 residualBER := omit,
1342 trafficHandlingPriority := omit,
1343 transferDelay := omit,
1344 guaranteedBitRateUplink := omit,
1345 guaranteedBitRateDownlink := omit,
1346 sourceStatisticsDescriptor := omit,
1347 signallingIndication := omit,
1348 spare4 := omit,
1349 maxBitrateDownlinkExt := omit,
1350 guaranteedBitRateDownlinkExt := omit,
1351 maxBitrateUplinkExt := omit,
1352 guaranteedBitRateUplinkExt := omit,
1353 maxBitrateDownlinkExt2 := omit,
1354 guaranteedBitRateDownlinkExt2 := omit,
1355 maxBitrateUplinkExt2 := omit,
1356 guaranteedBitRateUplinkExt2 := omit
1357}
1358
1359/* 10.5.6.4 / 3GPP TS 24.008 */
1360template (value) PDPAddressV t_AddrIPv4dyn := {
1361 pdpTypeOrg := '0001'B, /* IETF */
1362 spare := '0000'B,
1363 pdpTypeNum := '21'O, /* IPv4 */
1364 addressInfo := omit
1365}
1366template (value) PDPAddressV t_AddrIPv6dyn := {
1367 pdpTypeOrg := '0001'B, /* IETF */
1368 spare := '0000'B,
1369 pdpTypeNum := '53'O, /* IPv6 */
1370 addressInfo := omit
1371}
1372
Harald Welte37692d82018-02-18 15:21:34 +01001373template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001374 tid := '000'B,
1375 nsapi := '0101'B, /* < 5 are reserved */
1376 sapi := '0011'B, /* 3/5/9/11 */
1377 qos := t_QosDefault,
1378 addr := t_AddrIPv4dyn,
1379 apn := omit,
1380 pco := omit,
1381 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001382 gtp_resp_cause := int2oct(128, 1),
1383 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001384
1385 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001386 ggsn_tei_c := f_rnd_octstring(4),
1387 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001388 ggsn_ip_c := f_inet_addr(ggsn_ip),
1389 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001390 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001391
Harald Welteeded9ad2018-02-17 20:57:34 +01001392 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001393 sgsn_tei_u := omit,
1394 sgsn_ip_c := omit,
1395 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001396}
1397
Harald Welte37692d82018-02-18 15:21:34 +01001398template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1399 connId := 1,
1400 remName := f_inet_ntoa(ip),
1401 remPort := GTP1U_PORT
1402}
1403
1404template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1405 connId := 1,
1406 remName := f_inet_ntoa(ip),
1407 remPort := GTP1C_PORT
1408}
1409
1410private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1411 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1412 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1413}
1414
Harald Weltef7191672019-05-02 20:37:23 +02001415private altstep as_xid(PdpActPars apars, integer gb_idx := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001416 [] BSSGP[gb_idx].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001417 repeat;
1418 }
1419}
1420
1421template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1422 pDU_SN_UNITDATA := {
1423 nsapi := nsapi,
1424 moreBit := ?,
1425 snPduType := '1'B,
1426 firstSegmentIndicator := ?,
1427 spareBit := ?,
1428 pcomp := ?,
1429 dcomp := ?,
1430 npduNumber := ?,
1431 segmentNumber := ?,
1432 npduNumberContinued := ?,
1433 dataSegmentSnUnitdataPdu := payload
1434 }
1435}
1436
1437/* simple case: single segment, no compression */
1438template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1439 pDU_SN_UNITDATA := {
1440 nsapi := nsapi,
1441 moreBit := '0'B,
1442 snPduType := '1'B,
1443 firstSegmentIndicator := '1'B,
1444 spareBit := '0'B,
1445 pcomp := '0000'B,
1446 dcomp := '0000'B,
1447 npduNumber := '0000'B,
1448 segmentNumber := '0000'B,
1449 npduNumberContinued := '00'O,
1450 dataSegmentSnUnitdataPdu := payload
1451 }
1452}
1453
1454/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltef7191672019-05-02 20:37:23 +02001455private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1456runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001457 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1458 f_gtpu_send(apars, payload);
1459 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1460 alt {
Harald Weltef7191672019-05-02 20:37:23 +02001461 [] as_xid(apars, gb_idx);
Harald Welte955aa942019-05-03 01:29:29 +02001462 //[] BSSGP[gb_idx].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1463 [] BSSGP[gb_idx].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001464 }
1465}
1466
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001467/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Harald Weltef7191672019-05-02 20:37:23 +02001468private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer gb_idx := 0)
1469runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001470 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1471 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1472 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Harald Weltef7191672019-05-02 20:37:23 +02001473 BSSGP[gb_idx].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001474 /* Expect PDU via GTP from SGSN on simulated GGSN */
1475 alt {
1476 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1477 }
1478}
1479
Harald Welteeded9ad2018-02-17 20:57:34 +01001480private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001481 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001482
1483 /* first perform regular attach */
1484 f_TC_attach(id);
1485
1486 f_pdp_ctx_act(apars);
1487}
1488testcase TC_attach_pdp_act() runs on test_CT {
1489 var BSSGP_ConnHdlr vc_conn;
1490 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001491 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001492 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001493 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001494}
Harald Welteb2124b22018-02-16 22:26:56 +01001495
Harald Welte835b15f2018-02-18 14:39:11 +01001496/* PDP Context activation for not-attached subscriber; expect fail */
1497private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001498 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001499 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Harald Welte835b15f2018-02-18 14:39:11 +01001500 apars.apn, apars.pco));
1501 alt {
1502 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001503 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001504 setverdict(pass);
1505 }
1506 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1507 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001508 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001509 }
Harald Welte955aa942019-05-03 01:29:29 +02001510 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001511 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001512 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001513 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001514 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001515 }
1516}
1517testcase TC_pdp_act_unattached() runs on test_CT {
1518 var BSSGP_ConnHdlr vc_conn;
1519 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001520 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001521 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001522 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001523}
1524
Harald Welte37692d82018-02-18 15:21:34 +01001525/* ATTACH + PDP CTX ACT + user plane traffic */
1526private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1527 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1528
1529 /* first perform regular attach */
1530 f_TC_attach(id);
1531 /* then activate PDP context */
1532 f_pdp_ctx_act(apars);
1533 /* then transceive a downlink PDU */
1534 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1535 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1536}
1537testcase TC_attach_pdp_act_user() runs on test_CT {
1538 var BSSGP_ConnHdlr vc_conn;
1539 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001540 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001541 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001542 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001543}
1544
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001545/* ATTACH + PDP CTX ACT; reject from GGSN */
1546private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1547 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1548
1549 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1550 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1551
1552 /* first perform regular attach */
1553 f_TC_attach(id);
1554 /* then activate PDP context */
1555 f_pdp_ctx_act(apars);
1556}
1557testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1558 var BSSGP_ConnHdlr vc_conn;
1559 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001560 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001561 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001562 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001563}
Harald Welte835b15f2018-02-18 14:39:11 +01001564
Harald Welte6f203162018-02-18 22:04:55 +01001565/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1566private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1567 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1568
1569 /* first perform regular attach */
1570 f_TC_attach(id);
1571 /* then activate PDP context */
1572 f_pdp_ctx_act(apars);
1573 /* then transceive a downlink PDU */
1574 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1575 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1576
1577 f_pdp_ctx_deact_mo(apars, '00'O);
1578}
1579testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1580 var BSSGP_ConnHdlr vc_conn;
1581 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001582 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 +01001583 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001584 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001585}
1586
Harald Welte57b9b7f2018-02-18 22:28:13 +01001587/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1588private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1589 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1590
1591 /* first perform regular attach */
1592 f_TC_attach(id);
1593 /* then activate PDP context */
1594 f_pdp_ctx_act(apars);
1595 /* then transceive a downlink PDU */
1596 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1597 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1598
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001599 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001600}
1601testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1602 var BSSGP_ConnHdlr vc_conn;
1603 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001604 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 +01001605 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001606 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001607}
1608
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001609/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1610private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1611 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1612 var Gtp1cUnitdata g_ud;
1613 var integer i;
1614 var OCT1 cause_regular_deact := '24'O;
1615
1616 /* first perform regular attach + PDP context act */
1617 f_TC_attach(id);
1618 f_pdp_ctx_act(apars);
1619
1620 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1621 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1622
1623 for (i := 0; i < 2; i := i+1) {
1624 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1625 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1626 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1627 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1628 }
1629 }
1630
1631 alt {
1632 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1633 setverdict(pass);
1634 }
1635 [] as_xid(apars, 0);
1636 }
1637
1638 /* Make sure second DeactPdpAccept is sent: */
1639 timer T := 2.0;
1640 T.start;
1641 alt {
1642 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1643 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1644 }
1645 [] T.timeout {
1646 setverdict(pass);
1647 }
1648 }
1649
1650 setverdict(pass);
1651}
1652testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1653 var BSSGP_ConnHdlr vc_conn;
1654 f_init();
1655 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1656 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001657 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001658}
1659
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001660/* ATTACH + ATTACH (2nd) */
1661private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1662 g_pars.t_guard := 5.0;
1663
1664 /* first perform regular attach */
1665 f_TC_attach(id);
1666
1667 /* second to perform regular attach */
1668 f_TC_attach(id);
1669}
1670
1671
1672testcase TC_attach_second_attempt() runs on test_CT {
1673 var BSSGP_ConnHdlr vc_conn;
1674 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001675 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001676 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001677 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001678}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001679
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001680private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1681 var Gtp1cUnitdata g_ud;
1682 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1683 var integer seq_nr;
1684
1685 /* first perform regular attach */
1686 f_TC_attach(id);
1687 /* then activate PDP context */
1688 f_pdp_ctx_act(apars);
1689
1690 /* Wait to receive first echo request and send initial Restart counter */
1691 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1692 BSSGP[0].clear;
1693 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1694 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1695 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1696 }
1697
1698 /* At some point next echo request not answered will timeout and SGSN
1699 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1700 timer T := 3.0 * 6.0 + 16.0;
1701 T.start;
1702 alt {
1703 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1704 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1705 setverdict(pass);
1706 }
1707 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1708 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1709 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1710 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1711 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1712 repeat;
1713 }
1714 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1715 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1716 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1717 repeat;
1718 }
1719 [] T.timeout {
1720 setverdict(fail, "BSSGP DeactPdpReq not received");
1721 mtc.stop;
1722 }
1723 [] as_xid(apars);
1724 }
1725 T.stop
1726
1727 setverdict(pass);
1728}
1729/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1730testcase TC_attach_echo_timeout() runs on test_CT {
1731 var BSSGP_ConnHdlr vc_conn;
1732 g_use_echo := true;
1733 f_init();
1734 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1735 vc_conn.done;
1736 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001737 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001738}
1739
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001740private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001741 var Gtp1cUnitdata g_ud;
1742 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1743
1744 /* first perform regular attach */
1745 f_TC_attach(id);
1746 /* Activate a pdp context against the GGSN */
1747 f_pdp_ctx_act(apars);
1748 /* Wait to receive first echo request and send initial Restart counter */
1749 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1750 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1751 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1752 }
1753 /* Wait to receive second echo request and send incremented Restart
1754 counter. This will fake a restarted GGSN, and pdp ctx allocated
1755 should be released by SGSN */
1756 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1757 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1758 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1759 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1760 }
1761 var OCT1 cause_network_failure := int2oct(38, 1)
1762 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001763 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001764 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001765 setverdict(pass);
1766 }
1767 [] as_xid(apars);
1768 }
1769 setverdict(pass);
1770}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001771/* ATTACH + trigger Recovery procedure through EchoResp */
1772testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001773 var BSSGP_ConnHdlr vc_conn;
1774 g_use_echo := true
1775 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001776 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 +02001777 vc_conn.done;
1778 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001779 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001780}
1781
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001782private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1783 var Gtp1cUnitdata g_ud;
1784 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1785 var integer seq_nr := 23;
1786 var GtpPeer peer;
1787 /* first perform regular attach */
1788 f_TC_attach(id);
1789
1790 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1791 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1792 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1793 f_pdp_ctx_act(apars, true);
1794
1795 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1796/* received. */
1797 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1798
1799 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1800 would be great to have an active pdp context here before triggering
1801 Recovery, and making sure the the DEACT request is sent by the SGSN.
1802 */
1803
1804 /* Activate a pdp context against the GGSN, send incremented Recovery
1805 IE. This should trigger the recovery path, but still this specific
1806 CTX activation should work. */
1807 apars.exp_rej_cause := omit; /* default value for tests */
1808 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1809 f_pdp_ctx_act(apars, true);
1810
1811 setverdict(pass);
1812}
1813/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1814testcase TC_attach_restart_ctr_create() runs on test_CT {
1815 var BSSGP_ConnHdlr vc_conn;
1816 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001817 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 +02001818 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001819 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001820}
1821
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001822/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1823private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1824 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1825 var integer seq_nr := 23;
1826 var GtpPeer peer;
1827 var integer i;
1828
1829 /* first perform regular attach */
1830 f_TC_attach(id);
1831 /* then activate PDP context */
1832 f_pdp_ctx_act(apars);
1833
Alexander Couzens0e510e62018-07-28 23:06:00 +02001834 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001835 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1836 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1837
1838 for (i := 0; i < 5; i := i+1) {
1839 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001840 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001841 [] as_xid(apars);
1842 }
1843 }
1844
1845 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1846
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001847 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001848 setverdict(pass);
1849}
1850testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1851 var BSSGP_ConnHdlr vc_conn;
1852 f_init();
1853 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001854 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 +02001855 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001856 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001857}
1858
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001859/* ATTACH + PDP CTX ACT dropped + retrans */
1860private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1861 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1862 var Gtp1cUnitdata g_ud_first, g_ud_second;
1863 /* first perform regular attach */
1864 f_TC_attach(id);
1865
1866 /* then activate PDP context on the Gb side */
1867 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1868 apars.apn, apars.pco), 0);
1869
1870 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1871 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1872 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1873 if (g_ud_first != g_ud_second) {
1874 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1875 mtc.stop;
1876 }
1877 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1878 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1879 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1880 apars.sgsn_tei_c, apars.gtp_resp_cause,
1881 apars.ggsn_tei_c, apars.ggsn_tei_u,
1882 apars.nsapi,
1883 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1884 omit, omit));
1885 }
Harald Welte955aa942019-05-03 01:29:29 +02001886 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001887
1888 /* Now the same with Deact */
1889 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1890 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1891 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1892 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1893 if (g_ud_first != g_ud_second) {
1894 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1895 mtc.stop;
1896 }
1897 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1898 BSSGP[0].clear;
1899 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1900 }
1901 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001902 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001903 setverdict(pass);
1904 }
1905 [] as_xid(apars, 0);
1906 }
1907
1908 setverdict(pass);
1909}
1910testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1911 var BSSGP_ConnHdlr vc_conn;
1912 f_init();
1913 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1914 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001915 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001916}
1917
1918/* Test that SGSN GTP response retransmit queue works fine */
1919private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1920 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1921 var integer seq_nr := 23;
1922 var Gtp1cUnitdata g_ud_first, g_ud_second;
1923 var template Gtp1cUnitdata g_delete_req;
1924 /* first perform regular attach + PDP context act */
1925 f_TC_attach(id);
1926 f_pdp_ctx_act(apars);
1927
1928 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1929 BSSGP[0].clear;
1930 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1931 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1932 GTP.send(g_delete_req);
1933 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001934 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001935 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1936 }
1937 [] as_xid(apars, 0);
1938 }
1939 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1940 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1941 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1942 mtc.stop;
1943 }
1944 };
1945
1946 /* Send duplicate DeleteCtxReq */
1947 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1948 GTP.send(g_delete_req);
1949 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1950 if (g_ud_first != g_ud_second) {
1951 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1952 mtc.stop;
1953 }
1954 }
1955
1956 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1957 * is handled differently by SGSN (expect "non-existent" cause) */
1958 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1959 GTP.send(g_delete_req);
1960 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1961 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1962 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1963 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1964 mtc.stop;
1965 }
1966 }
1967
1968 setverdict(pass);
1969}
1970testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1971 var BSSGP_ConnHdlr vc_conn;
1972 f_init();
1973 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1974 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001975 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001976}
1977
Alexander Couzens5e307b42018-05-22 18:12:20 +02001978private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1979 /* MS: perform regular attach */
1980 f_TC_attach(id);
1981
1982 /* HLR: cancel the location request */
1983 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1984 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001985
1986 /* ensure no Detach Request got received */
1987 timer T := 5.0;
1988 T.start;
1989 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001990 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001991 T.stop;
1992 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001993 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001994 }
1995 [] T.timeout {
1996 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001997 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001998 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001999 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002000 repeat;
2001 }
2002 }
2003}
2004
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002005/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2006private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2007 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2008
2009 /* first perform regular attach */
2010 f_TC_attach(id);
2011 /* then activate PDP context */
2012 f_pdp_ctx_act(apars);
2013 /* then transceive a downlink PDU */
2014 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2015
2016 /* Send Error indication as response from upload PDU and expect deact towards MS */
2017 f_pdp_ctx_deact_mt(apars, true);
2018}
2019testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2020 var BSSGP_ConnHdlr vc_conn;
2021 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002022 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 +02002023 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002024 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002025}
2026
Alexander Couzens5e307b42018-05-22 18:12:20 +02002027testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2028 /* MS <-> SGSN: GMM Attach
2029 * HLR -> SGSN: Cancel Location Request
2030 * HLR <- SGSN: Cancel Location Ack
2031 */
2032 var BSSGP_ConnHdlr vc_conn;
2033 f_init();
2034 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002035 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002036 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002037 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002038}
2039
2040
Alexander Couzensc87967a2018-05-22 16:09:54 +02002041private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2042 /* MS: perform regular attach */
2043 f_TC_attach(id);
2044
2045 /* HLR: cancel the location request */
2046 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2047 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2048 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2049
2050 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002051 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002052 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002053
2054 setverdict(pass);
2055}
2056
2057testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2058 /* MS <-> SGSN: GMM Attach
2059 * HLR -> SGSN: Cancel Location Request
2060 * HLR <- SGSN: Cancel Location Ack
2061 * MS <- SGSN: Detach Request
2062 * SGSN-> MS: Detach Complete
2063 */
2064 var BSSGP_ConnHdlr vc_conn;
2065 f_init();
2066 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002067 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002068 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002069 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002070}
2071
2072
Alexander Couzens6c47f292018-05-22 17:09:49 +02002073private function f_hlr_location_cancel_request_unknown_subscriber(
2074 charstring id,
2075 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2076
2077 /* HLR: cancel the location request */
2078 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2079
2080 /* cause 2 = IMSI_UNKNOWN */
2081 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2082
2083 setverdict(pass);
2084}
2085
2086private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002087 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002088}
2089
2090testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2091 /* HLR -> SGSN: Cancel Location Request
2092 * HLR <- SGSN: Cancel Location Error
2093 */
2094
2095 var BSSGP_ConnHdlr vc_conn;
2096 f_init();
2097 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002098 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 +02002099 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002100 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002101}
2102
2103private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002104 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002105}
2106
2107testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2108 /* HLR -> SGSN: Cancel Location Request
2109 * HLR <- SGSN: Cancel Location Error
2110 */
2111
2112 var BSSGP_ConnHdlr vc_conn;
2113 f_init();
2114 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002115 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 +02002116 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002117 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002118}
2119
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002120private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2121 f_TC_attach(id);
2122 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2123}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002124
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002125testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2126 /* MS <-> SGSN: Attach
2127 * MS -> SGSN: Detach Req (Power off)
2128 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2129 */
2130 var BSSGP_ConnHdlr vc_conn;
2131 var integer id := 33;
2132 var charstring imsi := hex2str(f_gen_imsi(id));
2133
2134 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002135 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002136 vc_conn.done;
2137
2138 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002139 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002140}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002141
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002142/* Attempt an attach, but loose the Identification Request (IMEI) */
2143private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2144 var integer count_req := 0;
2145 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2146
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002147 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002148
2149 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002150 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002151 /* break */
2152 }
Harald Welte955aa942019-05-03 01:29:29 +02002153 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002154 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002155 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002156 repeat;
2157 }
Harald Welte955aa942019-05-03 01:29:29 +02002158 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002159 /* ignore ID REQ IMEI */
2160 count_req := count_req + 1;
2161 repeat;
2162 }
2163 }
2164 if (count_req != 5) {
2165 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002166 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002167 }
2168 setverdict(pass);
2169}
2170
2171testcase TC_attach_no_imei_response() runs on test_CT {
2172 /* MS -> SGSN: Attach Request IMSI
2173 * MS <- SGSN: Identity Request IMSI (optional)
2174 * MS -> SGSN: Identity Response IMSI (optional)
2175 * MS <- SGSN: Identity Request IMEI
2176 * MS -x SGSN: no response
2177 * MS <- SGSN: re-send: Identity Request IMEI 4x
2178 * MS <- SGSN: Attach Reject
2179 */
2180 var BSSGP_ConnHdlr vc_conn;
2181 f_init();
2182 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002183 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 +02002184 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002185 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002186}
2187
Alexander Couzens53f20562018-06-12 16:24:12 +02002188/* Attempt an attach, but loose the Identification Request (IMSI) */
2189private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2190 var integer count_req := 0;
2191 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2192
2193 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2194 g_pars.p_tmsi := 'c0000035'O;
2195
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002196 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02002197
2198 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002199 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002200 /* break */
2201 }
Harald Welte955aa942019-05-03 01:29:29 +02002202 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002203 /* ignore ID REQ IMSI */
2204 count_req := count_req + 1;
2205 repeat;
2206 }
Harald Welte955aa942019-05-03 01:29:29 +02002207 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002208 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002209 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002210 repeat;
2211 }
2212 }
2213 if (count_req != 5) {
2214 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002215 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002216 }
2217 setverdict(pass);
2218}
2219
2220testcase TC_attach_no_imsi_response() runs on test_CT {
2221 /* MS -> SGSN: Attach Request TMSI (unknown)
2222 * MS <- SGSN: Identity Request IMEI (optional)
2223 * MS -> SGSN: Identity Response IMEI (optional)
2224 * MS <- SGSN: Identity Request IMSI
2225 * MS -x SGSN: no response
2226 * MS <- SGSN: re-send: Identity Request IMSI 4x
2227 * MS <- SGSN: Attach Reject
2228 */
2229 var BSSGP_ConnHdlr vc_conn;
2230 f_init();
2231 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002232 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 +02002233 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002234 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002235}
2236
Alexander Couzenscf818962018-06-05 18:00:00 +02002237private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2238 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2239}
2240
2241testcase TC_attach_check_subscriber_list() runs on test_CT {
2242 /* MS <-> SGSN: Attach
2243 * VTY -> SGSN: Check if MS is in subscriber cache
2244 */
2245 var BSSGP_ConnHdlr vc_conn;
2246 var integer id := 34;
2247 var charstring imsi := hex2str(f_gen_imsi(id));
2248
2249 f_init();
2250 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002251 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002252 vc_conn.done;
2253
2254 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2255 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002256 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002257}
2258
Alexander Couzensf9858652018-06-07 16:14:53 +02002259private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2260 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002261 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002262
2263 /* unregister the old IMSI */
2264 f_bssgp_client_unregister(g_pars.imsi);
2265 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002266 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002267 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002268
2269 /* there is no auth */
2270 g_pars.net.expect_auth := false;
2271
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002272 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002273 f_gmm_auth();
2274 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002275 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002276 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002277 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002278 }
Harald Welte955aa942019-05-03 01:29:29 +02002279 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2280 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002281 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002282 setverdict(pass);
2283 }
2284 }
2285}
Alexander Couzens03d12242018-08-07 16:13:52 +02002286
2287private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2288
2289 f_TC_attach_closed_foreign(id);
2290 f_TC_attach_closed_imsi_added(id);
2291
2292}
2293
2294
Alexander Couzensf9858652018-06-07 16:14:53 +02002295testcase TC_attach_closed_add_vty() runs on test_CT {
2296 /* VTY-> SGSN: policy close
2297 * MS -> SGSN: Attach Request
2298 * MS <- SGSN: Identity Request IMSI
2299 * MS -> SGSN: Identity Response IMSI
2300 * MS <- SGSN: Attach Reject
2301 * VTY-> SGSN: policy imsi-acl add IMSI
2302 * MS -> SGSN: Attach Request
2303 * MS <- SGSN: Identity Request IMSI
2304 * MS -> SGSN: Identity Response IMSI
2305 * MS <- SGSN: Identity Request IMEI
2306 * MS -> SGSN: Identity Response IMEI
2307 * MS <- SGSN: Attach Accept
2308 */
2309 var BSSGP_ConnHdlr vc_conn;
2310 f_init();
2311 f_sleep(1.0);
2312 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2313 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002314 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2315 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002316 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002317 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002318 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002319 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002320}
2321
Alexander Couzens0085bd72018-06-12 19:08:44 +02002322/* Attempt an attach, but never answer a Attach Complete */
2323private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2324 var integer count_req := 0;
2325
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002326 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens0085bd72018-06-12 19:08:44 +02002327 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002328 /* Expect SGSN to perform LU with HLR */
2329 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002330
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002331 timer T := 10.0;
2332 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002333 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002334 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002335 /* break */
2336 }
Harald Welte955aa942019-05-03 01:29:29 +02002337 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002338 /* ignore */
2339 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002340 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002341 repeat;
2342 }
2343 }
2344 if (count_req != 5) {
2345 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002346 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002347 }
2348 setverdict(pass);
2349}
2350
2351testcase TC_attach_check_complete_resend() runs on test_CT {
2352 /* MS -> SGSN: Attach Request IMSI
2353 * MS <- SGSN: Identity Request *
2354 * MS -> SGSN: Identity Response *
2355 * MS <- SGSN: Attach Complete 5x
2356 */
2357 var BSSGP_ConnHdlr vc_conn;
2358 f_init();
2359 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002360 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 +02002361 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002362 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002363}
2364
Alexander Couzens5d56f522019-09-03 12:36:18 +02002365friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer bssgp := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002366 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002367 var PDU_DTAP_PS_MT mt;
2368 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002369
Alexander Couzens5d56f522019-09-03 12:36:18 +02002370 if (is_iu(bssgp)) {
2371 p_tmsi := g_pars.p_tmsi;
2372 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002373 /* then send RAU */
Alexander Couzens5d56f522019-09-03 12:36:18 +02002374 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002375 alt {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002376 [is_gb(bssgp)] BSSGP[bssgp].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
Harald Welte955aa942019-05-03 01:29:29 +02002377 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002378 f_send_l3(ts_GMM_RAU_COMPL, bssgp);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002379 setverdict(pass);
2380 }
Alexander Couzens5d56f522019-09-03 12:36:18 +02002381 [is_iu(bssgp)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2382 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, bssgp);
2383 f_send_l3(ts_GMM_RAU_COMPL, bssgp);
2384 setverdict(pass);
2385 }
2386
2387 [is_gb(bssgp)] BSSGP[bssgp].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002388 setverdict(fail, "Unexpected RAU Reject");
2389 mtc.stop;
2390 }
Alexander Couzens5d56f522019-09-03 12:36:18 +02002391 [is_iu(bssgp)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
2392 setverdict(fail, "Unexpected RAU Reject");
2393 mtc.stop;
2394 }
2395
2396 [is_iu(bssgp)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
2397 key_sts := ?)) {
2398 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2399 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
2400 }
2401 [is_gb(bssgp)] BSSGP[bssgp].receive { repeat; }
2402 [is_iu(bssgp)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002403 }
2404}
2405
Alexander Couzensbfda9212018-07-31 03:17:33 +02002406private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002407 /* first perform regular attach */
2408 f_TC_attach(id);
2409
2410 /* then send RAU */
2411 f_routing_area_update(g_pars.ra);
2412
2413 /* do another RAU */
2414 f_routing_area_update(g_pars.ra);
2415
2416 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2417}
2418
2419testcase TC_attach_rau_a_a() runs on test_CT {
2420 /* MS <-> SGSN: Successful Attach
2421 * MS -> SGSN: Routing Area Update Request
2422 * MS <- SGSN: Routing Area Update Accept
2423 * MS -> SGSN: Routing Area Update Request
2424 * MS <- SGSN: Routing Area Update Accept
2425 * MS -> SGSN: Detach (PowerOff)
2426 */
2427 var BSSGP_ConnHdlr vc_conn;
2428 f_init();
2429 f_sleep(1.0);
2430 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2431 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002432 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002433}
2434
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002435private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002436 f_TC_attach(id);
2437
2438 log("attach complete sending rau");
2439 f_routing_area_update(g_pars.ra, 0);
2440
2441 log("rau complete unregistering");
2442 f_bssgp_client_unregister(g_pars.imsi);
2443 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2444
2445 log("sending second RAU via different RA");
2446 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2447
2448 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2449}
2450
2451testcase TC_attach_rau_a_b() runs on test_CT {
2452 /* MS <-> SGSN: Successful Attach
2453 * MS -> SGSN: Routing Area _a_ Update Request
2454 * MS <- SGSN: Routing Area _a_ Update Accept
2455 * MS -> SGSN: Routing Area _b_ Update Request
2456 * MS <- SGSN: Routing Area _b_ Update Accept
2457 * MS -> SGSN: Detach (PowerOff)
2458 */
2459 var BSSGP_ConnHdlr vc_conn;
2460 f_init();
2461 f_sleep(1.0);
2462 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2463 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002464 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002465}
2466
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002467private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2468 var integer count_req := 0;
2469 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2470 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002471 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002472
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002473 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002474
2475 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002476 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002477 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2478 mtc.stop;
2479 }
Harald Welte955aa942019-05-03 01:29:29 +02002480 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002481 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002482 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002483 repeat;
2484 }
Harald Welte955aa942019-05-03 01:29:29 +02002485 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002486 /* send out a second GMM_Attach Request.
2487 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2488 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002489 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002490 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002491 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002492 }
2493 }
2494 f_sleep(1.0);
2495
2496 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2497 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002498 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002499 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002500 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002501 repeat;
2502 }
Harald Welte955aa942019-05-03 01:29:29 +02002503 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002504 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2505 mtc.stop;
2506 }
Harald Welte955aa942019-05-03 01:29:29 +02002507 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002508 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2509 mtc.stop;
2510 }
Harald Welte955aa942019-05-03 01:29:29 +02002511 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2512 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002513 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002514 setverdict(pass);
2515 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2516 }
2517 }
2518}
2519
2520testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2521 /* Testing if the SGSN ignore Attach Request with the exact same content */
2522 /* MS -> SGSN: Attach Request IMSI
2523 * MS <- SGSN: Identity Request IMSI (optional)
2524 * MS -> SGSN: Identity Response IMSI (optional)
2525 * MS <- SGSN: Identity Request IMEI
2526 * MS -> SGSN: Attach Request (2nd)
2527 * MS <- SGSN: Identity Response IMEI
2528 * MS <- SGSN: Attach Accept
2529 * MS -> SGSN: Attach Complete
2530 */
2531 var BSSGP_ConnHdlr vc_conn;
2532 f_init();
2533 f_sleep(1.0);
2534 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2535 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2536 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002537 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002538}
2539
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002540private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002541 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2542
2543 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2544
2545 /* send Attach Request */
2546 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2547 * 3G auth vectors */
2548 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2549 /* The thing is, if the solSACapability is 'omit', then the
2550 * revisionLevelIndicatior is at the wrong place! */
2551 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002552 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002553
2554 /* do the auth */
2555 var PDU_L3_MS_SGSN l3_mo;
2556 var PDU_L3_SGSN_MS l3_mt;
2557 var default di := activate(as_mm_identity());
2558
2559 var GSUP_IE auth_tuple;
2560 var template AuthenticationParameterAUTNTLV autn;
2561
2562 g_pars.vec := f_gen_auth_vec_3g();
2563 autn := {
2564 elementIdentifier := '28'O,
2565 lengthIndicator := lengthof(g_pars.vec.autn),
2566 autnValue := g_pars.vec.autn
2567 };
2568 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2569 g_pars.vec.sres,
2570 g_pars.vec.kc,
2571 g_pars.vec.ik,
2572 g_pars.vec.ck,
2573 g_pars.vec.autn,
2574 g_pars.vec.res));
2575 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2576 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2577 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2578
2579 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2580 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002581 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002582
2583 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002584 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002585
2586 /* wait for the GSUP resync request */
2587 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2588 g_pars.imsi,
2589 g_pars.vec.auts,
2590 g_pars.vec.rand));
2591
2592 /* generate new key material */
2593 g_pars.vec := f_gen_auth_vec_3g();
2594 autn := {
2595 elementIdentifier := '28'O,
2596 lengthIndicator := lengthof(g_pars.vec.autn),
2597 autnValue := g_pars.vec.autn
2598 };
2599
2600 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2601 g_pars.vec.sres,
2602 g_pars.vec.kc,
2603 g_pars.vec.ik,
2604 g_pars.vec.ck,
2605 g_pars.vec.autn,
2606 g_pars.vec.res));
2607 /* send new key material */
2608 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2609
2610 /* wait for the new Auth Request */
2611 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2612 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002613 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002614 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2615 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2616 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2617 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2618 valueField := substr(g_pars.vec.res, 0, 4)
2619 };
2620 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2621 elementIdentifier := '21'O,
2622 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2623 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2624 };
2625 l3_mo := valueof(auth_ciph_resp);
2626 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2627 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2628 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2629 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2630 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002631 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002632 deactivate(di);
2633
2634 /* Expect SGSN to perform LU with HLR */
2635 f_gmm_gsup_lu_isd();
2636
Harald Welte955aa942019-05-03 01:29:29 +02002637 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2638 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002639 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002640 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002641 setverdict(pass);
2642}
2643
2644testcase TC_attach_usim_resync() runs on test_CT {
2645 /* MS -> SGSN: Attach Request
2646 * MS <- SGSN: Identity Request IMSI
2647 * MS -> SGSN: Identity Response IMSI
2648 * MS <- SGSN: Identity Request IMEI
2649 * MS -> SGSN: Identity Response IMEI
2650 * HLR<- SGSN: SAI Request
2651 * HLR-> SGSN: SAI Response
2652 * MS <- SGSN: Auth Request
2653 * MS -> SGSN: Auth Failure (with AUTS)
2654 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2655 * HLR-> SGSN: SAI Response (new key material)
2656 * MS <- SGSN: Auth Request (new key material)
2657 * MS -> SGSN: Auth Response
2658 * MS <- SGSN: Attach Accept
2659 * MS -> SGSN: Attach Complete
2660 */
2661 var BSSGP_ConnHdlr vc_conn;
2662 f_init();
2663 f_sleep(1.0);
2664 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2665 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002666 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002667}
2668
Harald Weltea05b8072019-04-23 22:35:05 +02002669
2670/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2671private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2672 f_gmm_attach(false, false);
2673 f_sleep(1.0);
2674 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2675 /* try to detach to check if SGSN is still alive */
2676 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2677}
2678testcase TC_llc_null() runs on test_CT {
2679 var BSSGP_ConnHdlr vc_conn;
2680 f_init();
2681 f_sleep(1.0);
2682 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2683 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002684 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002685}
2686
Harald Welte645a1512019-04-23 23:18:23 +02002687/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2688private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2689 f_gmm_attach(false, false);
2690 f_sleep(1.0);
2691 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002692 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002693 setverdict(pass);
2694}
2695testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2696 var BSSGP_ConnHdlr vc_conn;
2697 f_init();
2698 f_sleep(1.0);
2699 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2700 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002701 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002702}
2703
2704/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2705private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2706 f_gmm_attach(false, false);
2707 f_sleep(1.0);
2708 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002709 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002710 setverdict(pass);
2711}
2712testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2713 var BSSGP_ConnHdlr vc_conn;
2714 f_init();
2715 f_sleep(1.0);
2716 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2717 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002718 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002719}
2720
Harald Welte2aaac1b2019-05-02 10:02:53 +02002721/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2722private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2723 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2724 var template (value) XID_Information xid;
2725 var template XID_Information xid_rx;
2726
2727 /* first perform regular attach */
2728 f_TC_attach(id);
2729 /* then activate PDP context */
2730 f_pdp_ctx_act(apars);
2731
2732 /* start MO XID */
2733 xid := { ts_XID_L3(''O) };
2734 xid_rx := { tr_XID_L3(''O) };
2735 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2736 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002737 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002738 [] as_xid(apars);
2739 }
2740 setverdict(pass);
2741}
2742testcase TC_xid_empty_l3() runs on test_CT {
2743 var BSSGP_ConnHdlr vc_conn;
2744 f_init();
2745 f_sleep(1.0);
2746 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2747 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002748 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002749}
2750
2751private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2752 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2753 var template (value) XID_Information xid;
2754 var template XID_Information xid_rx;
2755
2756 /* first perform regular attach */
2757 f_TC_attach(id);
2758 /* then activate PDP context */
2759 f_pdp_ctx_act(apars);
2760
2761 /* start MO XID */
2762 xid := { ts_XID_N201U(1234) };
2763 xid_rx := { tr_XID_N201U(1234) };
2764 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2765 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002766 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002767 [] as_xid(apars);
2768 }
2769 setverdict(pass);
2770}
2771testcase TC_xid_n201u() runs on test_CT {
2772 var BSSGP_ConnHdlr vc_conn;
2773 f_init();
2774 f_sleep(1.0);
2775 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2776 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002777 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002778}
2779
Alexander Couzens6bee0872019-05-11 01:48:50 +02002780private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2781 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2782
2783 /* first perform regular attach */
2784 f_TC_attach(id);
2785 /* then activate PDP context */
2786 f_pdp_ctx_act(apars);
2787 /* do a normal detach */
2788 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2789}
2790
2791testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2792 /* MS -> SGSN: Attach Request
2793 * MS <-> SGSN: [..]
2794 * MS -> SGSN: Attach Complete
2795 * MS -> SGSN: PDP Activate Request
2796 * MS <- SGSN: PDP Activate Accept
2797 * MS -> SGSN: GMM Detach Request
2798 * MS <- SGSN: GMM Detach Accept
2799 */
2800 var BSSGP_ConnHdlr vc_conn;
2801 f_init();
2802 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2803 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002804 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002805}
Harald Welte645a1512019-04-23 23:18:23 +02002806
Harald Welte5ac31492018-02-15 20:39:13 +01002807control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002808 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002809 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002810 execute( TC_attach_umts_aka_umts_res() );
2811 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002812 execute( TC_attach_auth_id_timeout() );
2813 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002814 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002815 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002816 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002817 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002818 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002819 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002820 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002821 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002822 execute( TC_attach_closed_add_vty(), 20.0 );
2823 execute( TC_attach_check_subscriber_list(), 20.0 );
2824 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002825 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002826 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2827 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2828 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2829 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002830 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002831 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002832 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002833 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002834 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002835 execute( TC_detach_unknown_nopoweroff() );
2836 execute( TC_detach_unknown_poweroff() );
2837 execute( TC_detach_nopoweroff() );
2838 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002839 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002840 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002841 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002842 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002843 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002844 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002845 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002846 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002847 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002848 execute( TC_attach_restart_ctr_echo() );
2849 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002850 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002851 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2852 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002853 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002854 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002855 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002856
Harald Welte2aaac1b2019-05-02 10:02:53 +02002857 execute( TC_xid_empty_l3() );
2858 execute( TC_xid_n201u() );
2859
Harald Weltea05b8072019-04-23 22:35:05 +02002860 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002861 execute( TC_llc_sabm_dm_llgmm() );
2862 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002863}
Harald Welte96a33b02018-02-04 10:36:22 +01002864
2865
2866
2867}