blob: 281dcc9ed199641c0ba7afcfe348e6b45af9532a [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 Couzensb1ce1182019-09-15 22:43:40 +0200489friend function is_gb(integer ran_index) return boolean {
490 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200491}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200492friend function is_iu(integer ran_index) return boolean {
493 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200494}
495
Alexander Couzens0507ec32019-09-15 22:41:22 +0200496function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200497 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200498 BSSGP[ran_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[ran_index], llc_enc));
Harald Weltea05b8072019-04-23 22:35:05 +0200499}
500
Alexander Couzens0507ec32019-09-15 22:41:22 +0200501private function f_send_l3_gmm_llc(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_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 Couzens0507ec32019-09-15 22:41:22 +0200505 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_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 */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200542function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
543 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200544 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 {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200551 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200552 }
553}
554
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200555altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100556 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200557 [is_gb(ran_index)] BSSGP[ran_index].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 Couzensb1ce1182019-09-15 22:43:40 +0200559 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100560 repeat;
561 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200562 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200563 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200564 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200565 repeat;
566 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200567 [is_gb(ran_index)] BSSGP[ran_index].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 Couzensb1ce1182019-09-15 22:43:40 +0200569 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200570 repeat;
571 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200573 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200574 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
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 */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200580function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200581runs 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 Couzensb1ce1182019-09-15 22:43:40 +0200585 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
586 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200587 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(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200596function f_gmm_auth (boolean umts_aka_challenge := false, boolean force_gsm_sres := false, integer ran_index := 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;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200599 var default di := activate(as_mm_identity(ran_index));
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;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200634 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
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 Couzensb1ce1182019-09-15 22:43:40 +0200656 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200657
658 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200659 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200660 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));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200664 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200665 }
666 }
Harald Welte76dee092018-02-16 22:12:59 +0100667 } else {
668 /* wait for identity procedure */
669 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100670 }
Harald Welte76dee092018-02-16 22:12:59 +0100671
Harald Welte5ac31492018-02-15 20:39:13 +0100672 deactivate(di);
673}
674
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200675function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100676 g_pars.p_tmsi := p_tmsi;
677 /* update TLLI */
678 g_pars.tlli_old := g_pars.tlli;
679 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200680 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
Harald Weltef70997d2018-02-17 10:11:19 +0100681}
682
Harald Welte04683d02018-02-16 22:43:45 +0100683function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
684 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100685 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200686 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100687 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200688 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200689 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100690 }
Harald Welte04683d02018-02-16 22:43:45 +0100691 g_pars.ra := aa.routingAreaIdentification;
692 if (ispresent(aa.allocatedPTMSI)) {
693 if (not g_pars.net.expect_ptmsi) {
694 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200695 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100696 }
Harald Weltef70997d2018-02-17 10:11:19 +0100697 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100698 }
699 if (ispresent(aa.msIdentity)) {
700 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200701 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100702 }
703 /* P-TMSI.sig */
704 if (ispresent(aa.ptmsiSignature)) {
705 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
706 }
707 /* updateTimer */
708 // aa.readyTimer
709 /* T3302, T3319, T3323, T3312_ext, T3324 */
710}
711
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200712function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100713 /* mandatory IE */
714 g_pars.ra := ra.routingAreaId;
715 if (ispresent(ra.allocatedPTMSI)) {
716 if (not g_pars.net.expect_ptmsi) {
717 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200718 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100719 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200720 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100721 }
722 if (ispresent(ra.msIdentity)) {
723 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200724 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100725 }
726 /* P-TMSI.sig */
727 if (ispresent(ra.ptmsiSignature)) {
728 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
729 }
730 /* updateTimer */
731 // aa.readyTimer
732 /* T3302, T3319, T3323, T3312_ext, T3324 */
733}
734
735
Harald Welte5a4fa042018-02-16 20:59:21 +0100736function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
737 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
738}
739
Harald Welte23178c52018-02-17 09:36:33 +0100740/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100741private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileL3_CommonIE_Types.MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100742 if (ispresent(g_pars.p_tmsi)) {
743 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
744 } else {
745 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
746 }
747}
748
Harald Welte311ec272018-02-17 09:40:03 +0100749private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100750 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100751 /* Expect MSC to perform LU with HLR */
752 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100753 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
754 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
755 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100756 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
757 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
758}
759
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200760friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100761 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200762 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 +0200763 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100764
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200765 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
766 * 3G auth vectors */
767 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
768 /* The thing is, if the solSACapability is 'omit', then the
769 * revisionLevelIndicatior is at the wrong place! */
770 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
771
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200772 f_send_l3(attach_req, ran_index);
773 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200774 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100775 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100776
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200777 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200778 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
779
Harald Welte04683d02018-02-16 22:43:45 +0100780 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200781 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200782
783 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200784 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200785 as_iu_release_compl_disc();
786 }
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200787}
788
789private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
790 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100791 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100792}
793
794testcase TC_attach() runs on test_CT {
795 var BSSGP_ConnHdlr vc_conn;
796 f_init();
797 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200798 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100799 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200800 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100801}
802
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100803testcase TC_attach_mnc3() runs on test_CT {
804 var BSSGP_ConnHdlr vc_conn;
805 f_init('023042'H);
806 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200807 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100808 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200809 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100810}
811
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200812private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
813 f_gmm_attach(true, false);
814 setverdict(pass);
815}
816testcase TC_attach_umts_aka_umts_res() runs on test_CT {
817 var BSSGP_ConnHdlr vc_conn;
818 f_init();
819 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200820 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200821 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200822 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200823}
824
825private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
826 f_gmm_attach(true, true);
827 setverdict(pass);
828}
829testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
830 var BSSGP_ConnHdlr vc_conn;
831 f_init();
832 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200833 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200834 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200835 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200836}
837
Harald Welte5b7c8122018-02-16 21:48:17 +0100838/* MS never responds to ID REQ, expect ATTACH REJECT */
839private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100840 var RoutingAreaIdentificationV old_ra := f_random_RAI();
841
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200842 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100843 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200844 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100845 /* don't send ID Response */
846 repeat;
847 }
Harald Welte955aa942019-05-03 01:29:29 +0200848 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100849 setverdict(pass);
850 }
Harald Welte955aa942019-05-03 01:29:29 +0200851 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100852 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200853 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100854 }
855 }
856}
857testcase TC_attach_auth_id_timeout() runs on test_CT {
858 var BSSGP_ConnHdlr vc_conn;
859 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200860 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 +0100861 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200862 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100863}
864
865/* HLR never responds to SAI REQ, expect ATTACH REJECT */
866private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100867 var RoutingAreaIdentificationV old_ra := f_random_RAI();
868
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200869 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100870 alt {
871 [] as_mm_identity();
872 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
873 }
874 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200875 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100876 setverdict(pass);
877}
878testcase TC_attach_auth_sai_timeout() runs on test_CT {
879 var BSSGP_ConnHdlr vc_conn;
880 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200881 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100882 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200883 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100884}
885
Harald Weltefe253882018-02-17 09:25:00 +0100886/* HLR rejects SAI, expect ATTACH REJECT */
887private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100888 var RoutingAreaIdentificationV old_ra := f_random_RAI();
889
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200890 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100891 alt {
892 [] as_mm_identity();
893 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
894 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
895 }
896 }
Harald Welte955aa942019-05-03 01:29:29 +0200897 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100898 setverdict(pass);
899}
900testcase TC_attach_auth_sai_reject() runs on test_CT {
901 var BSSGP_ConnHdlr vc_conn;
902 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200903 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100904 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200905 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100906}
907
Harald Welte5b7c8122018-02-16 21:48:17 +0100908/* HLR never responds to UL REQ, expect ATTACH REJECT */
909private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200910 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100911 var RoutingAreaIdentificationV old_ra := f_random_RAI();
912
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200913 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100914 f_gmm_auth();
915 /* Expect MSC to perform LU with HLR */
916 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
917 /* Never follow-up with ISD_REQ or UL_RES */
918 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200919 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100920 setverdict(pass);
921 }
Harald Welte955aa942019-05-03 01:29:29 +0200922 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
923 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100924 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200925 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100926 }
927 }
928}
929testcase TC_attach_gsup_lu_timeout() runs on test_CT {
930 var BSSGP_ConnHdlr vc_conn;
931 f_init();
932 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200933 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100934 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200935 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100936}
937
Harald Welteb7c14e92018-02-17 09:29:16 +0100938/* HLR rejects UL REQ, expect ATTACH REJECT */
939private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200940 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100941 var RoutingAreaIdentificationV old_ra := f_random_RAI();
942
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200943 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100944 f_gmm_auth();
945 /* Expect MSC to perform LU with HLR */
946 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
947 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
948 }
949 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200950 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +0100951 setverdict(pass);
952 }
Harald Welte955aa942019-05-03 01:29:29 +0200953 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
954 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +0100955 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200956 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +0100957 }
958 }
959}
960testcase TC_attach_gsup_lu_reject() runs on test_CT {
961 var BSSGP_ConnHdlr vc_conn;
962 f_init();
963 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200964 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +0100965 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200966 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +0100967}
968
969
Harald Welte3823e2e2018-02-16 21:53:48 +0100970/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
971private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200972 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +0100973 var RoutingAreaIdentificationV old_ra := f_random_RAI();
974
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200975 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +0100976 f_gmm_auth();
977 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100978 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +0100979
Harald Welte955aa942019-05-03 01:29:29 +0200980 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
981 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +0100982 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200983 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +0100984 setverdict(pass);
985}
Harald Welte3823e2e2018-02-16 21:53:48 +0100986testcase TC_attach_combined() runs on test_CT {
987 var BSSGP_ConnHdlr vc_conn;
988 f_init();
989 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200990 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +0100991 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200992 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +0100993}
994
Harald Welte76dee092018-02-16 22:12:59 +0100995/* Attempt of GPRS ATTACH in 'accept all' mode */
996private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200997 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +0100998 var RoutingAreaIdentificationV old_ra := f_random_RAI();
999
1000 g_pars.net.expect_auth := false;
1001
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001002 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001003 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001004 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1005 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001006 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001007 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001008 setverdict(pass);
1009}
1010testcase TC_attach_accept_all() runs on test_CT {
1011 var BSSGP_ConnHdlr vc_conn;
1012 f_init();
1013 f_sleep(1.0);
1014 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001015 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001016 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001017 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001018}
Harald Welte5b7c8122018-02-16 21:48:17 +01001019
Harald Welteb2124b22018-02-16 22:26:56 +01001020/* Attempt of GPRS ATTACH in 'accept all' mode */
1021private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001022 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1023
1024 /* Simulate a foreign IMSI */
1025 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001026 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001027
1028 g_pars.net.expect_auth := false;
1029
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001030 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001031 alt {
1032 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001033 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001034 setverdict(pass);
1035 }
Harald Welte955aa942019-05-03 01:29:29 +02001036 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001037 setverdict(pass);
1038 }
Harald Welte955aa942019-05-03 01:29:29 +02001039 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001040 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001041 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001042 }
Harald Welteb2124b22018-02-16 22:26:56 +01001043 }
1044}
1045testcase TC_attach_closed() runs on test_CT {
1046 var BSSGP_ConnHdlr vc_conn;
1047 f_init();
1048 f_sleep(1.0);
1049 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1050 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001051 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001052 vc_conn.done;
1053 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001054 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001055 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001056 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001057}
1058
Harald Welte04683d02018-02-16 22:43:45 +01001059/* Routing Area Update from Unknown TLLI -> REJECT */
1060private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001061 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1062
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001063 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 +01001064 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001065 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
Harald Welte04683d02018-02-16 22:43:45 +01001066 setverdict(pass);
1067 }
1068 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001069 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001070 }
1071}
1072testcase TC_rau_unknown() runs on test_CT {
1073 var BSSGP_ConnHdlr vc_conn;
1074 f_init();
1075 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001076 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001077 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001078 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001079}
1080
Harald Welte91636de2018-02-17 10:16:14 +01001081private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001082 /* first perform regular attach */
1083 f_TC_attach(id);
1084
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001085 f_routing_area_update(g_pars.ra);
1086
Harald Welte91636de2018-02-17 10:16:14 +01001087}
1088testcase TC_attach_rau() runs on test_CT {
1089 var BSSGP_ConnHdlr vc_conn;
1090 f_init();
1091 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001092 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001093 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001094 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001095}
Harald Welte04683d02018-02-16 22:43:45 +01001096
Harald Welte6abb9fe2018-02-17 15:24:48 +01001097/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001098function f_detach_mo(BIT3 detach_type, boolean power_off, boolean expect_purge, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001099 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001100 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001101 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001102 if (expect_purge) {
1103 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1104 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1105 }
1106 T.start;
1107 alt {
1108 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1109 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001110 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001111 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001112 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001113 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001114 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001115 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001116 /* TODO: check if any PDP contexts are deactivated on network side? */
1117 }
1118 [power_off] T.timeout {
1119 setverdict(pass);
1120 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001121 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001122 g_pars.ra := omit;
1123 setverdict(pass);
1124 /* TODO: check if any PDP contexts are deactivated on network side? */
1125 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001126 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001127 if (power_off) {
1128 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1129 } else {
1130 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1131 }
1132 mtc.stop;
1133 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001134 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001135 }
1136}
1137
1138/* IMSI DETACH (non-power-off) for unknown TLLI */
1139private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1140 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1141}
1142testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1143 var BSSGP_ConnHdlr vc_conn;
1144 f_init();
1145 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001146 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001147 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001148 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001149}
1150
1151/* IMSI DETACH (power-off) for unknown TLLI */
1152private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1153 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1154}
1155testcase TC_detach_unknown_poweroff() runs on test_CT {
1156 var BSSGP_ConnHdlr vc_conn;
1157 f_init();
1158 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001159 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001160 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001161 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001162}
1163
1164/* IMSI DETACH (non-power-off) for known TLLI */
1165private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1166 /* first perform regular attach */
1167 f_TC_attach(id);
1168
1169 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1170}
1171testcase TC_detach_nopoweroff() runs on test_CT {
1172 var BSSGP_ConnHdlr vc_conn;
1173 f_init();
1174 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001175 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001176 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001177 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001178}
1179
1180/* IMSI DETACH (power-off) for known TLLI */
1181private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1182 /* first perform regular attach */
1183 f_TC_attach(id);
1184
1185 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1186}
1187testcase TC_detach_poweroff() runs on test_CT {
1188 var BSSGP_ConnHdlr vc_conn;
1189 f_init();
1190 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001191 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001192 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001193 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001194}
1195
Harald Welteeded9ad2018-02-17 20:57:34 +01001196type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001197 BIT3 tid, /* L3 Transaction ID */
1198 BIT4 nsapi, /* SNDCP NSAPI */
1199 BIT4 sapi, /* LLC SAPI */
1200 QoSV qos, /* QoS parameters */
1201 PDPAddressV addr, /* IP address */
1202 octetstring apn optional, /* APN name */
1203 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1204 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001205 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001206 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001207
Harald Welte822f9102018-02-18 20:39:06 +01001208 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1209 OCT4 ggsn_tei_u, /* GGSN TEI User */
1210 octetstring ggsn_ip_c, /* GGSN IP Control */
1211 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001212 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001213
Harald Welte822f9102018-02-18 20:39:06 +01001214 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1215 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1216 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1217 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001218};
1219
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001220
1221private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1222 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1223 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1224 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1225 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1226 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1227 f_gtp_register_teid(apars.ggsn_tei_c);
1228 f_gtp_register_teid(apars.ggsn_tei_u);
1229}
1230
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001231function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001232runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001233 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1234 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001235 var template Recovery_gtpc recovery := omit;
1236
1237 if (send_recovery) {
1238 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1239 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001240
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001241 f_send_l3(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001242 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001243 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1244 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1245 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1246 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1247 apars.sgsn_tei_c, apars.gtp_resp_cause,
1248 apars.ggsn_tei_c, apars.ggsn_tei_u,
1249 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001250 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1251 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001252 }
1253 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001254 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001255 setverdict(pass);
1256 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001257 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001258 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001259 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001260 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001261 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001262 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001263 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001264 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001265 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001266 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1267 mtc.stop;
1268 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001269 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001270 setverdict(pass);
1271 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001272 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001273 }
1274}
1275
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001276function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001277runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001278 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1279 var Gtp1cUnitdata g_ud;
1280
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001281 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001282 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1283 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001284 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001285 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1286 }
1287 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001288 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001289 setverdict(pass);
1290 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001291 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001292 }
1293}
1294
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001295function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001296runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001297 var Gtp1cUnitdata g_ud;
1298 var integer seq_nr := 23;
1299 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1300
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001301 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001302 if (error_ind) {
1303 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1304 } else {
1305 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1306 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001307
1308 timer T := 5.0;
1309 T.start;
1310
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001311 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001312 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1313 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001314 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001315 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1316 repeat;
1317 }
1318 [] T.timeout {
1319 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1320 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001321 }
1322}
1323
Harald Welte6f203162018-02-18 22:04:55 +01001324
Harald Welteeded9ad2018-02-17 20:57:34 +01001325/* Table 10.5.156/3GPP TS 24.008 */
1326template (value) QoSV t_QosDefault := {
1327 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1328 delayClass := '100'B, /* best effort */
1329 spare1 := '00'B,
1330 precedenceClass := '010'B, /* normal */
1331 spare2 := '0'B,
1332 peakThroughput := '0000'B, /* subscribed */
1333 meanThroughput := '00000'B, /* subscribed */
1334 spare3 := '000'B,
1335 deliverErroneusSDU := omit,
1336 deliveryOrder := omit,
1337 trafficClass := omit,
1338 maxSDUSize := omit,
1339 maxBitrateUplink := omit,
1340 maxBitrateDownlink := omit,
1341 sduErrorRatio := omit,
1342 residualBER := omit,
1343 trafficHandlingPriority := omit,
1344 transferDelay := omit,
1345 guaranteedBitRateUplink := omit,
1346 guaranteedBitRateDownlink := omit,
1347 sourceStatisticsDescriptor := omit,
1348 signallingIndication := omit,
1349 spare4 := omit,
1350 maxBitrateDownlinkExt := omit,
1351 guaranteedBitRateDownlinkExt := omit,
1352 maxBitrateUplinkExt := omit,
1353 guaranteedBitRateUplinkExt := omit,
1354 maxBitrateDownlinkExt2 := omit,
1355 guaranteedBitRateDownlinkExt2 := omit,
1356 maxBitrateUplinkExt2 := omit,
1357 guaranteedBitRateUplinkExt2 := omit
1358}
1359
1360/* 10.5.6.4 / 3GPP TS 24.008 */
1361template (value) PDPAddressV t_AddrIPv4dyn := {
1362 pdpTypeOrg := '0001'B, /* IETF */
1363 spare := '0000'B,
1364 pdpTypeNum := '21'O, /* IPv4 */
1365 addressInfo := omit
1366}
1367template (value) PDPAddressV t_AddrIPv6dyn := {
1368 pdpTypeOrg := '0001'B, /* IETF */
1369 spare := '0000'B,
1370 pdpTypeNum := '53'O, /* IPv6 */
1371 addressInfo := omit
1372}
1373
Harald Welte37692d82018-02-18 15:21:34 +01001374template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001375 tid := '000'B,
1376 nsapi := '0101'B, /* < 5 are reserved */
1377 sapi := '0011'B, /* 3/5/9/11 */
1378 qos := t_QosDefault,
1379 addr := t_AddrIPv4dyn,
1380 apn := omit,
1381 pco := omit,
1382 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001383 gtp_resp_cause := int2oct(128, 1),
1384 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001385
1386 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001387 ggsn_tei_c := f_rnd_octstring(4),
1388 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001389 ggsn_ip_c := f_inet_addr(ggsn_ip),
1390 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001391 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001392
Harald Welteeded9ad2018-02-17 20:57:34 +01001393 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001394 sgsn_tei_u := omit,
1395 sgsn_ip_c := omit,
1396 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001397}
1398
Harald Welte37692d82018-02-18 15:21:34 +01001399template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1400 connId := 1,
1401 remName := f_inet_ntoa(ip),
1402 remPort := GTP1U_PORT
1403}
1404
1405template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1406 connId := 1,
1407 remName := f_inet_ntoa(ip),
1408 remPort := GTP1C_PORT
1409}
1410
1411private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1412 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1413 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1414}
1415
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001416private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1417 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001418 repeat;
1419 }
1420}
1421
1422template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1423 pDU_SN_UNITDATA := {
1424 nsapi := nsapi,
1425 moreBit := ?,
1426 snPduType := '1'B,
1427 firstSegmentIndicator := ?,
1428 spareBit := ?,
1429 pcomp := ?,
1430 dcomp := ?,
1431 npduNumber := ?,
1432 segmentNumber := ?,
1433 npduNumberContinued := ?,
1434 dataSegmentSnUnitdataPdu := payload
1435 }
1436}
1437
1438/* simple case: single segment, no compression */
1439template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1440 pDU_SN_UNITDATA := {
1441 nsapi := nsapi,
1442 moreBit := '0'B,
1443 snPduType := '1'B,
1444 firstSegmentIndicator := '1'B,
1445 spareBit := '0'B,
1446 pcomp := '0000'B,
1447 dcomp := '0000'B,
1448 npduNumber := '0000'B,
1449 segmentNumber := '0000'B,
1450 npduNumberContinued := '00'O,
1451 dataSegmentSnUnitdataPdu := payload
1452 }
1453}
1454
1455/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001456private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001457runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001458 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1459 f_gtpu_send(apars, payload);
1460 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1461 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001462 [] as_xid(apars, ran_index);
1463 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
1464 [] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
Harald Welte37692d82018-02-18 15:21:34 +01001465 }
1466}
1467
Pau Espin Pedrol8be4d192018-07-18 13:43:44 +02001468/* Transceive given 'payload' as MT message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001469private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001470runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001471 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1472 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1473 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001474 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001475 /* Expect PDU via GTP from SGSN on simulated GGSN */
1476 alt {
1477 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1478 }
1479}
1480
Harald Welteeded9ad2018-02-17 20:57:34 +01001481private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001482 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001483
1484 /* first perform regular attach */
1485 f_TC_attach(id);
1486
1487 f_pdp_ctx_act(apars);
1488}
1489testcase TC_attach_pdp_act() runs on test_CT {
1490 var BSSGP_ConnHdlr vc_conn;
1491 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001492 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001493 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001494 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001495}
Harald Welteb2124b22018-02-16 22:26:56 +01001496
Harald Welte835b15f2018-02-18 14:39:11 +01001497/* PDP Context activation for not-attached subscriber; expect fail */
1498private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001499 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001500 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 +01001501 apars.apn, apars.pco));
1502 alt {
1503 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001504 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001505 setverdict(pass);
1506 }
1507 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1508 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001509 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001510 }
Harald Welte955aa942019-05-03 01:29:29 +02001511 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001512 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001513 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001514 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001515 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001516 }
1517}
1518testcase TC_pdp_act_unattached() runs on test_CT {
1519 var BSSGP_ConnHdlr vc_conn;
1520 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001521 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001522 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001523 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001524}
1525
Harald Welte37692d82018-02-18 15:21:34 +01001526/* ATTACH + PDP CTX ACT + user plane traffic */
1527private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1528 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1529
1530 /* first perform regular attach */
1531 f_TC_attach(id);
1532 /* then activate PDP context */
1533 f_pdp_ctx_act(apars);
1534 /* then transceive a downlink PDU */
1535 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1536 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1537}
1538testcase TC_attach_pdp_act_user() runs on test_CT {
1539 var BSSGP_ConnHdlr vc_conn;
1540 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001541 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001542 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001543 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001544}
1545
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001546/* ATTACH + PDP CTX ACT; reject from GGSN */
1547private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1548 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1549
1550 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1551 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1552
1553 /* first perform regular attach */
1554 f_TC_attach(id);
1555 /* then activate PDP context */
1556 f_pdp_ctx_act(apars);
1557}
1558testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1559 var BSSGP_ConnHdlr vc_conn;
1560 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001561 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001562 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001563 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001564}
Harald Welte835b15f2018-02-18 14:39:11 +01001565
Harald Welte6f203162018-02-18 22:04:55 +01001566/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1567private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1568 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1569
1570 /* first perform regular attach */
1571 f_TC_attach(id);
1572 /* then activate PDP context */
1573 f_pdp_ctx_act(apars);
1574 /* then transceive a downlink PDU */
1575 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1576 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1577
1578 f_pdp_ctx_deact_mo(apars, '00'O);
1579}
1580testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1581 var BSSGP_ConnHdlr vc_conn;
1582 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001583 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 +01001584 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001585 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001586}
1587
Harald Welte57b9b7f2018-02-18 22:28:13 +01001588/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1589private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1590 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1591
1592 /* first perform regular attach */
1593 f_TC_attach(id);
1594 /* then activate PDP context */
1595 f_pdp_ctx_act(apars);
1596 /* then transceive a downlink PDU */
1597 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1598 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1599
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001600 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001601}
1602testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1603 var BSSGP_ConnHdlr vc_conn;
1604 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001605 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 +01001606 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001607 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001608}
1609
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001610/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1611private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1612 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1613 var Gtp1cUnitdata g_ud;
1614 var integer i;
1615 var OCT1 cause_regular_deact := '24'O;
1616
1617 /* first perform regular attach + PDP context act */
1618 f_TC_attach(id);
1619 f_pdp_ctx_act(apars);
1620
1621 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1622 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1623
1624 for (i := 0; i < 2; i := i+1) {
1625 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1626 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1627 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1628 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1629 }
1630 }
1631
1632 alt {
1633 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1634 setverdict(pass);
1635 }
1636 [] as_xid(apars, 0);
1637 }
1638
1639 /* Make sure second DeactPdpAccept is sent: */
1640 timer T := 2.0;
1641 T.start;
1642 alt {
1643 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1644 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1645 }
1646 [] T.timeout {
1647 setverdict(pass);
1648 }
1649 }
1650
1651 setverdict(pass);
1652}
1653testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1654 var BSSGP_ConnHdlr vc_conn;
1655 f_init();
1656 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1657 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001658 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001659}
1660
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001661/* ATTACH + ATTACH (2nd) */
1662private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1663 g_pars.t_guard := 5.0;
1664
1665 /* first perform regular attach */
1666 f_TC_attach(id);
1667
1668 /* second to perform regular attach */
1669 f_TC_attach(id);
1670}
1671
1672
1673testcase TC_attach_second_attempt() runs on test_CT {
1674 var BSSGP_ConnHdlr vc_conn;
1675 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001676 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001677 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001678 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001679}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001680
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001681private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1682 var Gtp1cUnitdata g_ud;
1683 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1684 var integer seq_nr;
1685
1686 /* first perform regular attach */
1687 f_TC_attach(id);
1688 /* then activate PDP context */
1689 f_pdp_ctx_act(apars);
1690
1691 /* Wait to receive first echo request and send initial Restart counter */
1692 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1693 BSSGP[0].clear;
1694 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1695 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1696 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1697 }
1698
1699 /* At some point next echo request not answered will timeout and SGSN
1700 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1701 timer T := 3.0 * 6.0 + 16.0;
1702 T.start;
1703 alt {
1704 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1705 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1706 setverdict(pass);
1707 }
1708 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1709 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1710 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1711 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1712 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1713 repeat;
1714 }
1715 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1716 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1717 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1718 repeat;
1719 }
1720 [] T.timeout {
1721 setverdict(fail, "BSSGP DeactPdpReq not received");
1722 mtc.stop;
1723 }
1724 [] as_xid(apars);
1725 }
1726 T.stop
1727
1728 setverdict(pass);
1729}
1730/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1731testcase TC_attach_echo_timeout() runs on test_CT {
1732 var BSSGP_ConnHdlr vc_conn;
1733 g_use_echo := true;
1734 f_init();
1735 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1736 vc_conn.done;
1737 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001738 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001739}
1740
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001741private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001742 var Gtp1cUnitdata g_ud;
1743 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1744
1745 /* first perform regular attach */
1746 f_TC_attach(id);
1747 /* Activate a pdp context against the GGSN */
1748 f_pdp_ctx_act(apars);
1749 /* Wait to receive first echo request and send initial Restart counter */
1750 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1751 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1752 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1753 }
1754 /* Wait to receive second echo request and send incremented Restart
1755 counter. This will fake a restarted GGSN, and pdp ctx allocated
1756 should be released by SGSN */
1757 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1758 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1759 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1760 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1761 }
1762 var OCT1 cause_network_failure := int2oct(38, 1)
1763 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001764 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001765 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001766 setverdict(pass);
1767 }
1768 [] as_xid(apars);
1769 }
1770 setverdict(pass);
1771}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001772/* ATTACH + trigger Recovery procedure through EchoResp */
1773testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001774 var BSSGP_ConnHdlr vc_conn;
1775 g_use_echo := true
1776 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001777 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 +02001778 vc_conn.done;
1779 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001780 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001781}
1782
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001783private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1784 var Gtp1cUnitdata g_ud;
1785 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1786 var integer seq_nr := 23;
1787 var GtpPeer peer;
1788 /* first perform regular attach */
1789 f_TC_attach(id);
1790
1791 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1792 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1793 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1794 f_pdp_ctx_act(apars, true);
1795
1796 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1797/* received. */
1798 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1799
1800 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1801 would be great to have an active pdp context here before triggering
1802 Recovery, and making sure the the DEACT request is sent by the SGSN.
1803 */
1804
1805 /* Activate a pdp context against the GGSN, send incremented Recovery
1806 IE. This should trigger the recovery path, but still this specific
1807 CTX activation should work. */
1808 apars.exp_rej_cause := omit; /* default value for tests */
1809 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1810 f_pdp_ctx_act(apars, true);
1811
1812 setverdict(pass);
1813}
1814/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1815testcase TC_attach_restart_ctr_create() runs on test_CT {
1816 var BSSGP_ConnHdlr vc_conn;
1817 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001818 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 +02001819 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001820 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001821}
1822
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001823/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1824private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1825 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1826 var integer seq_nr := 23;
1827 var GtpPeer peer;
1828 var integer i;
1829
1830 /* first perform regular attach */
1831 f_TC_attach(id);
1832 /* then activate PDP context */
1833 f_pdp_ctx_act(apars);
1834
Alexander Couzens0e510e62018-07-28 23:06:00 +02001835 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001836 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1837 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1838
1839 for (i := 0; i < 5; i := i+1) {
1840 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001841 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001842 [] as_xid(apars);
1843 }
1844 }
1845
1846 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1847
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001848 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001849 setverdict(pass);
1850}
1851testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1852 var BSSGP_ConnHdlr vc_conn;
1853 f_init();
1854 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001855 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 +02001856 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001857 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001858}
1859
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001860/* ATTACH + PDP CTX ACT dropped + retrans */
1861private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1862 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1863 var Gtp1cUnitdata g_ud_first, g_ud_second;
1864 /* first perform regular attach */
1865 f_TC_attach(id);
1866
1867 /* then activate PDP context on the Gb side */
1868 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1869 apars.apn, apars.pco), 0);
1870
1871 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1872 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1873 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1874 if (g_ud_first != g_ud_second) {
1875 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1876 mtc.stop;
1877 }
1878 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1879 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1880 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1881 apars.sgsn_tei_c, apars.gtp_resp_cause,
1882 apars.ggsn_tei_c, apars.ggsn_tei_u,
1883 apars.nsapi,
1884 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1885 omit, omit));
1886 }
Harald Welte955aa942019-05-03 01:29:29 +02001887 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001888
1889 /* Now the same with Deact */
1890 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1891 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1892 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1893 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1894 if (g_ud_first != g_ud_second) {
1895 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1896 mtc.stop;
1897 }
1898 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1899 BSSGP[0].clear;
1900 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1901 }
1902 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001903 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001904 setverdict(pass);
1905 }
1906 [] as_xid(apars, 0);
1907 }
1908
1909 setverdict(pass);
1910}
1911testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1912 var BSSGP_ConnHdlr vc_conn;
1913 f_init();
1914 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1915 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001916 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001917}
1918
1919/* Test that SGSN GTP response retransmit queue works fine */
1920private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1921 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1922 var integer seq_nr := 23;
1923 var Gtp1cUnitdata g_ud_first, g_ud_second;
1924 var template Gtp1cUnitdata g_delete_req;
1925 /* first perform regular attach + PDP context act */
1926 f_TC_attach(id);
1927 f_pdp_ctx_act(apars);
1928
1929 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1930 BSSGP[0].clear;
1931 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1932 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1933 GTP.send(g_delete_req);
1934 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001935 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001936 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
1937 }
1938 [] as_xid(apars, 0);
1939 }
1940 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
1941 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
1942 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
1943 mtc.stop;
1944 }
1945 };
1946
1947 /* Send duplicate DeleteCtxReq */
1948 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
1949 GTP.send(g_delete_req);
1950 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
1951 if (g_ud_first != g_ud_second) {
1952 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
1953 mtc.stop;
1954 }
1955 }
1956
1957 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
1958 * is handled differently by SGSN (expect "non-existent" cause) */
1959 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
1960 GTP.send(g_delete_req);
1961 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
1962 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
1963 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
1964 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
1965 mtc.stop;
1966 }
1967 }
1968
1969 setverdict(pass);
1970}
1971testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
1972 var BSSGP_ConnHdlr vc_conn;
1973 f_init();
1974 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
1975 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001976 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001977}
1978
Alexander Couzens5e307b42018-05-22 18:12:20 +02001979private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
1980 /* MS: perform regular attach */
1981 f_TC_attach(id);
1982
1983 /* HLR: cancel the location request */
1984 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
1985 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02001986
1987 /* ensure no Detach Request got received */
1988 timer T := 5.0;
1989 T.start;
1990 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001991 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02001992 T.stop;
1993 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02001994 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001995 }
1996 [] T.timeout {
1997 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02001998 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02001999 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002000 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002001 repeat;
2002 }
2003 }
2004}
2005
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002006/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2007private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2008 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2009
2010 /* first perform regular attach */
2011 f_TC_attach(id);
2012 /* then activate PDP context */
2013 f_pdp_ctx_act(apars);
2014 /* then transceive a downlink PDU */
2015 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2016
2017 /* Send Error indication as response from upload PDU and expect deact towards MS */
2018 f_pdp_ctx_deact_mt(apars, true);
2019}
2020testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2021 var BSSGP_ConnHdlr vc_conn;
2022 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002023 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 +02002024 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002025 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002026}
2027
Alexander Couzens5e307b42018-05-22 18:12:20 +02002028testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2029 /* MS <-> SGSN: GMM Attach
2030 * HLR -> SGSN: Cancel Location Request
2031 * HLR <- SGSN: Cancel Location Ack
2032 */
2033 var BSSGP_ConnHdlr vc_conn;
2034 f_init();
2035 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002036 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002037 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002038 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002039}
2040
2041
Alexander Couzensc87967a2018-05-22 16:09:54 +02002042private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2043 /* MS: perform regular attach */
2044 f_TC_attach(id);
2045
2046 /* HLR: cancel the location request */
2047 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2048 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2049 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2050
2051 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002052 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002053 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002054
2055 setverdict(pass);
2056}
2057
2058testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2059 /* MS <-> SGSN: GMM Attach
2060 * HLR -> SGSN: Cancel Location Request
2061 * HLR <- SGSN: Cancel Location Ack
2062 * MS <- SGSN: Detach Request
2063 * SGSN-> MS: Detach Complete
2064 */
2065 var BSSGP_ConnHdlr vc_conn;
2066 f_init();
2067 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002068 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002069 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002070 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002071}
2072
2073
Alexander Couzens6c47f292018-05-22 17:09:49 +02002074private function f_hlr_location_cancel_request_unknown_subscriber(
2075 charstring id,
2076 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2077
2078 /* HLR: cancel the location request */
2079 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2080
2081 /* cause 2 = IMSI_UNKNOWN */
2082 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2083
2084 setverdict(pass);
2085}
2086
2087private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002088 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002089}
2090
2091testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2092 /* HLR -> SGSN: Cancel Location Request
2093 * HLR <- SGSN: Cancel Location Error
2094 */
2095
2096 var BSSGP_ConnHdlr vc_conn;
2097 f_init();
2098 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002099 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 +02002100 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002101 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002102}
2103
2104private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002105 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002106}
2107
2108testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2109 /* HLR -> SGSN: Cancel Location Request
2110 * HLR <- SGSN: Cancel Location Error
2111 */
2112
2113 var BSSGP_ConnHdlr vc_conn;
2114 f_init();
2115 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002116 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 +02002117 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002118 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002119}
2120
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002121private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2122 f_TC_attach(id);
2123 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2124}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002125
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002126testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2127 /* MS <-> SGSN: Attach
2128 * MS -> SGSN: Detach Req (Power off)
2129 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2130 */
2131 var BSSGP_ConnHdlr vc_conn;
2132 var integer id := 33;
2133 var charstring imsi := hex2str(f_gen_imsi(id));
2134
2135 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002136 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002137 vc_conn.done;
2138
2139 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002140 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002141}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002142
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002143/* Attempt an attach, but loose the Identification Request (IMEI) */
2144private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2145 var integer count_req := 0;
2146 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2147
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002148 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 +02002149
2150 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002151 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002152 /* break */
2153 }
Harald Welte955aa942019-05-03 01:29:29 +02002154 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002155 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002156 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002157 repeat;
2158 }
Harald Welte955aa942019-05-03 01:29:29 +02002159 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002160 /* ignore ID REQ IMEI */
2161 count_req := count_req + 1;
2162 repeat;
2163 }
2164 }
2165 if (count_req != 5) {
2166 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002167 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002168 }
2169 setverdict(pass);
2170}
2171
2172testcase TC_attach_no_imei_response() runs on test_CT {
2173 /* MS -> SGSN: Attach Request IMSI
2174 * MS <- SGSN: Identity Request IMSI (optional)
2175 * MS -> SGSN: Identity Response IMSI (optional)
2176 * MS <- SGSN: Identity Request IMEI
2177 * MS -x SGSN: no response
2178 * MS <- SGSN: re-send: Identity Request IMEI 4x
2179 * MS <- SGSN: Attach Reject
2180 */
2181 var BSSGP_ConnHdlr vc_conn;
2182 f_init();
2183 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002184 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 +02002185 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002186 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002187}
2188
Alexander Couzens53f20562018-06-12 16:24:12 +02002189/* Attempt an attach, but loose the Identification Request (IMSI) */
2190private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2191 var integer count_req := 0;
2192 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2193
2194 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2195 g_pars.p_tmsi := 'c0000035'O;
2196
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002197 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 +02002198
2199 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002200 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002201 /* break */
2202 }
Harald Welte955aa942019-05-03 01:29:29 +02002203 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002204 /* ignore ID REQ IMSI */
2205 count_req := count_req + 1;
2206 repeat;
2207 }
Harald Welte955aa942019-05-03 01:29:29 +02002208 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002209 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002210 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002211 repeat;
2212 }
2213 }
2214 if (count_req != 5) {
2215 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002216 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002217 }
2218 setverdict(pass);
2219}
2220
2221testcase TC_attach_no_imsi_response() runs on test_CT {
2222 /* MS -> SGSN: Attach Request TMSI (unknown)
2223 * MS <- SGSN: Identity Request IMEI (optional)
2224 * MS -> SGSN: Identity Response IMEI (optional)
2225 * MS <- SGSN: Identity Request IMSI
2226 * MS -x SGSN: no response
2227 * MS <- SGSN: re-send: Identity Request IMSI 4x
2228 * MS <- SGSN: Attach Reject
2229 */
2230 var BSSGP_ConnHdlr vc_conn;
2231 f_init();
2232 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002233 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 +02002234 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002235 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002236}
2237
Alexander Couzenscf818962018-06-05 18:00:00 +02002238private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2239 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2240}
2241
2242testcase TC_attach_check_subscriber_list() runs on test_CT {
2243 /* MS <-> SGSN: Attach
2244 * VTY -> SGSN: Check if MS is in subscriber cache
2245 */
2246 var BSSGP_ConnHdlr vc_conn;
2247 var integer id := 34;
2248 var charstring imsi := hex2str(f_gen_imsi(id));
2249
2250 f_init();
2251 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002252 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002253 vc_conn.done;
2254
2255 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2256 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002257 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002258}
2259
Alexander Couzensf9858652018-06-07 16:14:53 +02002260private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2261 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002262 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002263
2264 /* unregister the old IMSI */
2265 f_bssgp_client_unregister(g_pars.imsi);
2266 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002267 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002268 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002269
2270 /* there is no auth */
2271 g_pars.net.expect_auth := false;
2272
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002273 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002274 f_gmm_auth();
2275 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002276 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002277 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002278 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002279 }
Harald Welte955aa942019-05-03 01:29:29 +02002280 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2281 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002282 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002283 setverdict(pass);
2284 }
2285 }
2286}
Alexander Couzens03d12242018-08-07 16:13:52 +02002287
2288private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2289
2290 f_TC_attach_closed_foreign(id);
2291 f_TC_attach_closed_imsi_added(id);
2292
2293}
2294
2295
Alexander Couzensf9858652018-06-07 16:14:53 +02002296testcase TC_attach_closed_add_vty() runs on test_CT {
2297 /* VTY-> SGSN: policy close
2298 * MS -> SGSN: Attach Request
2299 * MS <- SGSN: Identity Request IMSI
2300 * MS -> SGSN: Identity Response IMSI
2301 * MS <- SGSN: Attach Reject
2302 * VTY-> SGSN: policy imsi-acl add IMSI
2303 * MS -> SGSN: Attach Request
2304 * MS <- SGSN: Identity Request IMSI
2305 * MS -> SGSN: Identity Response IMSI
2306 * MS <- SGSN: Identity Request IMEI
2307 * MS -> SGSN: Identity Response IMEI
2308 * MS <- SGSN: Attach Accept
2309 */
2310 var BSSGP_ConnHdlr vc_conn;
2311 f_init();
2312 f_sleep(1.0);
2313 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2314 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002315 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2316 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002317 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002318 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002319 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002320 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002321}
2322
Alexander Couzens0085bd72018-06-12 19:08:44 +02002323/* Attempt an attach, but never answer a Attach Complete */
2324private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2325 var integer count_req := 0;
2326
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002327 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 +02002328 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002329 /* Expect SGSN to perform LU with HLR */
2330 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002331
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002332 timer T := 10.0;
2333 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002334 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002335 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002336 /* break */
2337 }
Harald Welte955aa942019-05-03 01:29:29 +02002338 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002339 /* ignore */
2340 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002341 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002342 repeat;
2343 }
2344 }
2345 if (count_req != 5) {
2346 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002347 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002348 }
2349 setverdict(pass);
2350}
2351
2352testcase TC_attach_check_complete_resend() runs on test_CT {
2353 /* MS -> SGSN: Attach Request IMSI
2354 * MS <- SGSN: Identity Request *
2355 * MS -> SGSN: Identity Response *
2356 * MS <- SGSN: Attach Complete 5x
2357 */
2358 var BSSGP_ConnHdlr vc_conn;
2359 f_init();
2360 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002361 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 +02002362 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002363 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002364}
2365
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002366friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002367 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002368 var PDU_DTAP_PS_MT mt;
2369 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002370
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002371 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002372 p_tmsi := g_pars.p_tmsi;
2373 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002374 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002375 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, g_pars.ra, false, omit, omit, p_tmsi), ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002376 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002377 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2378 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2379 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002380 setverdict(pass);
2381 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002382 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2383 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2384 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002385 setverdict(pass);
2386 }
2387
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002388 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002389 setverdict(fail, "Unexpected RAU Reject");
2390 mtc.stop;
2391 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002392 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002393 setverdict(fail, "Unexpected RAU Reject");
2394 mtc.stop;
2395 }
2396
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002397 [is_iu(ran_index)] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
Alexander Couzens5d56f522019-09-03 12:36:18 +02002398 key_sts := ?)) {
2399 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2400 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002401 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens5d56f522019-09-03 12:36:18 +02002402 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002403 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2404 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002405 }
2406}
2407
Alexander Couzensbfda9212018-07-31 03:17:33 +02002408private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002409 /* first perform regular attach */
2410 f_TC_attach(id);
2411
2412 /* then send RAU */
2413 f_routing_area_update(g_pars.ra);
2414
2415 /* do another RAU */
2416 f_routing_area_update(g_pars.ra);
2417
2418 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2419}
2420
2421testcase TC_attach_rau_a_a() runs on test_CT {
2422 /* MS <-> SGSN: Successful Attach
2423 * MS -> SGSN: Routing Area Update Request
2424 * MS <- SGSN: Routing Area Update Accept
2425 * MS -> SGSN: Routing Area Update Request
2426 * MS <- SGSN: Routing Area Update Accept
2427 * MS -> SGSN: Detach (PowerOff)
2428 */
2429 var BSSGP_ConnHdlr vc_conn;
2430 f_init();
2431 f_sleep(1.0);
2432 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2433 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002434 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002435}
2436
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002437private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002438 f_TC_attach(id);
2439
2440 log("attach complete sending rau");
2441 f_routing_area_update(g_pars.ra, 0);
2442
2443 log("rau complete unregistering");
2444 f_bssgp_client_unregister(g_pars.imsi);
2445 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2446
2447 log("sending second RAU via different RA");
2448 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2449
2450 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2451}
2452
2453testcase TC_attach_rau_a_b() runs on test_CT {
2454 /* MS <-> SGSN: Successful Attach
2455 * MS -> SGSN: Routing Area _a_ Update Request
2456 * MS <- SGSN: Routing Area _a_ Update Accept
2457 * MS -> SGSN: Routing Area _b_ Update Request
2458 * MS <- SGSN: Routing Area _b_ Update Accept
2459 * MS -> SGSN: Detach (PowerOff)
2460 */
2461 var BSSGP_ConnHdlr vc_conn;
2462 f_init();
2463 f_sleep(1.0);
2464 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2465 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002466 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002467}
2468
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002469private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2470 var integer count_req := 0;
2471 var MobileL3_CommonIE_Types.MobileIdentityLV mi;
2472 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002473 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002474
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002475 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002476
2477 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002478 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002479 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2480 mtc.stop;
2481 }
Harald Welte955aa942019-05-03 01:29:29 +02002482 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002483 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002484 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002485 repeat;
2486 }
Harald Welte955aa942019-05-03 01:29:29 +02002487 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002488 /* send out a second GMM_Attach Request.
2489 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2490 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002491 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002492 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002493 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002494 }
2495 }
2496 f_sleep(1.0);
2497
2498 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2499 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002500 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002501 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002502 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002503 repeat;
2504 }
Harald Welte955aa942019-05-03 01:29:29 +02002505 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002506 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2507 mtc.stop;
2508 }
Harald Welte955aa942019-05-03 01:29:29 +02002509 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002510 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2511 mtc.stop;
2512 }
Harald Welte955aa942019-05-03 01:29:29 +02002513 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2514 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002515 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002516 setverdict(pass);
2517 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2518 }
2519 }
2520}
2521
2522testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2523 /* Testing if the SGSN ignore Attach Request with the exact same content */
2524 /* MS -> SGSN: Attach Request IMSI
2525 * MS <- SGSN: Identity Request IMSI (optional)
2526 * MS -> SGSN: Identity Response IMSI (optional)
2527 * MS <- SGSN: Identity Request IMEI
2528 * MS -> SGSN: Attach Request (2nd)
2529 * MS <- SGSN: Identity Response IMEI
2530 * MS <- SGSN: Attach Accept
2531 * MS -> SGSN: Attach Complete
2532 */
2533 var BSSGP_ConnHdlr vc_conn;
2534 f_init();
2535 f_sleep(1.0);
2536 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2537 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2538 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002539 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002540}
2541
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002542private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002543 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2544
2545 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2546
2547 /* send Attach Request */
2548 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2549 * 3G auth vectors */
2550 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2551 /* The thing is, if the solSACapability is 'omit', then the
2552 * revisionLevelIndicatior is at the wrong place! */
2553 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002554 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002555
2556 /* do the auth */
2557 var PDU_L3_MS_SGSN l3_mo;
2558 var PDU_L3_SGSN_MS l3_mt;
2559 var default di := activate(as_mm_identity());
2560
2561 var GSUP_IE auth_tuple;
2562 var template AuthenticationParameterAUTNTLV autn;
2563
2564 g_pars.vec := f_gen_auth_vec_3g();
2565 autn := {
2566 elementIdentifier := '28'O,
2567 lengthIndicator := lengthof(g_pars.vec.autn),
2568 autnValue := g_pars.vec.autn
2569 };
2570 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2571 g_pars.vec.sres,
2572 g_pars.vec.kc,
2573 g_pars.vec.ik,
2574 g_pars.vec.ck,
2575 g_pars.vec.autn,
2576 g_pars.vec.res));
2577 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2578 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2579 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2580
2581 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2582 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002583 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002584
2585 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002586 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002587
2588 /* wait for the GSUP resync request */
2589 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2590 g_pars.imsi,
2591 g_pars.vec.auts,
2592 g_pars.vec.rand));
2593
2594 /* generate new key material */
2595 g_pars.vec := f_gen_auth_vec_3g();
2596 autn := {
2597 elementIdentifier := '28'O,
2598 lengthIndicator := lengthof(g_pars.vec.autn),
2599 autnValue := g_pars.vec.autn
2600 };
2601
2602 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2603 g_pars.vec.sres,
2604 g_pars.vec.kc,
2605 g_pars.vec.ik,
2606 g_pars.vec.ck,
2607 g_pars.vec.autn,
2608 g_pars.vec.res));
2609 /* send new key material */
2610 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2611
2612 /* wait for the new Auth Request */
2613 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2614 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002615 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002616 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2617 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2618 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2619 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2620 valueField := substr(g_pars.vec.res, 0, 4)
2621 };
2622 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2623 elementIdentifier := '21'O,
2624 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2625 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2626 };
2627 l3_mo := valueof(auth_ciph_resp);
2628 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2629 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2630 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2631 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2632 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002633 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002634 deactivate(di);
2635
2636 /* Expect SGSN to perform LU with HLR */
2637 f_gmm_gsup_lu_isd();
2638
Harald Welte955aa942019-05-03 01:29:29 +02002639 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2640 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002641 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002642 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002643 setverdict(pass);
2644}
2645
2646testcase TC_attach_usim_resync() runs on test_CT {
2647 /* MS -> SGSN: Attach Request
2648 * MS <- SGSN: Identity Request IMSI
2649 * MS -> SGSN: Identity Response IMSI
2650 * MS <- SGSN: Identity Request IMEI
2651 * MS -> SGSN: Identity Response IMEI
2652 * HLR<- SGSN: SAI Request
2653 * HLR-> SGSN: SAI Response
2654 * MS <- SGSN: Auth Request
2655 * MS -> SGSN: Auth Failure (with AUTS)
2656 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2657 * HLR-> SGSN: SAI Response (new key material)
2658 * MS <- SGSN: Auth Request (new key material)
2659 * MS -> SGSN: Auth Response
2660 * MS <- SGSN: Attach Accept
2661 * MS -> SGSN: Attach Complete
2662 */
2663 var BSSGP_ConnHdlr vc_conn;
2664 f_init();
2665 f_sleep(1.0);
2666 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2667 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002668 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002669}
2670
Harald Weltea05b8072019-04-23 22:35:05 +02002671
2672/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2673private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2674 f_gmm_attach(false, false);
2675 f_sleep(1.0);
2676 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2677 /* try to detach to check if SGSN is still alive */
2678 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2679}
2680testcase TC_llc_null() runs on test_CT {
2681 var BSSGP_ConnHdlr vc_conn;
2682 f_init();
2683 f_sleep(1.0);
2684 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2685 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002686 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002687}
2688
Harald Welte645a1512019-04-23 23:18:23 +02002689/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2690private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2691 f_gmm_attach(false, false);
2692 f_sleep(1.0);
2693 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002694 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002695 setverdict(pass);
2696}
2697testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2698 var BSSGP_ConnHdlr vc_conn;
2699 f_init();
2700 f_sleep(1.0);
2701 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2702 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002703 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002704}
2705
2706/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2707private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2708 f_gmm_attach(false, false);
2709 f_sleep(1.0);
2710 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002711 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002712 setverdict(pass);
2713}
2714testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2715 var BSSGP_ConnHdlr vc_conn;
2716 f_init();
2717 f_sleep(1.0);
2718 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2719 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002720 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002721}
2722
Harald Welte2aaac1b2019-05-02 10:02:53 +02002723/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2724private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2725 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2726 var template (value) XID_Information xid;
2727 var template XID_Information xid_rx;
2728
2729 /* first perform regular attach */
2730 f_TC_attach(id);
2731 /* then activate PDP context */
2732 f_pdp_ctx_act(apars);
2733
2734 /* start MO XID */
2735 xid := { ts_XID_L3(''O) };
2736 xid_rx := { tr_XID_L3(''O) };
2737 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2738 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002739 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002740 [] as_xid(apars);
2741 }
2742 setverdict(pass);
2743}
2744testcase TC_xid_empty_l3() runs on test_CT {
2745 var BSSGP_ConnHdlr vc_conn;
2746 f_init();
2747 f_sleep(1.0);
2748 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2749 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002750 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002751}
2752
2753private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2754 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2755 var template (value) XID_Information xid;
2756 var template XID_Information xid_rx;
2757
2758 /* first perform regular attach */
2759 f_TC_attach(id);
2760 /* then activate PDP context */
2761 f_pdp_ctx_act(apars);
2762
2763 /* start MO XID */
2764 xid := { ts_XID_N201U(1234) };
2765 xid_rx := { tr_XID_N201U(1234) };
2766 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2767 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002768 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002769 [] as_xid(apars);
2770 }
2771 setverdict(pass);
2772}
2773testcase TC_xid_n201u() runs on test_CT {
2774 var BSSGP_ConnHdlr vc_conn;
2775 f_init();
2776 f_sleep(1.0);
2777 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2778 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002779 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002780}
2781
Alexander Couzens6bee0872019-05-11 01:48:50 +02002782private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2783 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2784
2785 /* first perform regular attach */
2786 f_TC_attach(id);
2787 /* then activate PDP context */
2788 f_pdp_ctx_act(apars);
2789 /* do a normal detach */
2790 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2791}
2792
2793testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2794 /* MS -> SGSN: Attach Request
2795 * MS <-> SGSN: [..]
2796 * MS -> SGSN: Attach Complete
2797 * MS -> SGSN: PDP Activate Request
2798 * MS <- SGSN: PDP Activate Accept
2799 * MS -> SGSN: GMM Detach Request
2800 * MS <- SGSN: GMM Detach Accept
2801 */
2802 var BSSGP_ConnHdlr vc_conn;
2803 f_init();
2804 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2805 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002806 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002807}
Harald Welte645a1512019-04-23 23:18:23 +02002808
Harald Welte5ac31492018-02-15 20:39:13 +01002809control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002810 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002811 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002812 execute( TC_attach_umts_aka_umts_res() );
2813 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002814 execute( TC_attach_auth_id_timeout() );
2815 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002816 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002817 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002818 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002819 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002820 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002821 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002822 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002823 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002824 execute( TC_attach_closed_add_vty(), 20.0 );
2825 execute( TC_attach_check_subscriber_list(), 20.0 );
2826 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002827 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002828 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2829 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2830 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2831 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002832 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002833 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002834 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002835 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002836 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002837 execute( TC_detach_unknown_nopoweroff() );
2838 execute( TC_detach_unknown_poweroff() );
2839 execute( TC_detach_nopoweroff() );
2840 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002841 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002842 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002843 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002844 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002845 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002846 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002847 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002848 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002849 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002850 execute( TC_attach_restart_ctr_echo() );
2851 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002852 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002853 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2854 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002855 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002856 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002857 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002858
Harald Welte2aaac1b2019-05-02 10:02:53 +02002859 execute( TC_xid_empty_l3() );
2860 execute( TC_xid_n201u() );
2861
Harald Weltea05b8072019-04-23 22:35:05 +02002862 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002863 execute( TC_llc_sabm_dm_llgmm() );
2864 execute( TC_llc_sabm_dm_ll5() );
Harald Welte5ac31492018-02-15 20:39:13 +01002865}
Harald Welte96a33b02018-02-04 10:36:22 +01002866
2867
2868
2869}