blob: b42020d0840fec98b52865b59372f0f4ea348d02 [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;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020072 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020073 local_udp_port := 21010,
74 local_ip := "127.0.0.1",
75 remote_udp_port := 23000,
76 remote_ip := "127.0.0.1",
77 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020078 nsei := 96,
79 role_sgsn := false,
80 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020081 },
82 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020083 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020084 local_udp_port := 21011,
85 local_ip := "127.0.0.1",
86 remote_udp_port := 23000,
87 remote_ip := "127.0.0.1",
88 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020089 nsei := 97,
90 role_sgsn := false,
91 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020092 },
93 {
Alexander Couzense0f7c542020-09-13 17:25:18 +020094 address_family := AF_INET,
Alexander Couzensf3c1b412018-08-24 00:42:51 +020095 local_udp_port := 21012,
96 local_ip := "127.0.0.1",
97 remote_udp_port := 23000,
98 remote_ip := "127.0.0.1",
99 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +0200100 nsei := 98,
101 role_sgsn := false,
102 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200103 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200104 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200105
106 RAN_Configurations mp_ranap_cfg := {
107 {
108 transport := RANAP_TRANSPORT_IuCS,
109 sccp_service_type := "mtp3_itu",
110 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
111 own_pc := 195,
112 own_ssn := 142,
113 peer_pc := 188, /* 0.23.4 */
114 peer_ssn := 142,
115 sio := '83'O,
116 rctx := 2
117 }
118 }
Harald Welte5ac31492018-02-15 20:39:13 +0100119};
120
121type record GbInstance {
122 NS_CT vc_NS,
123 BSSGP_CT vc_BSSGP,
124 BssgpConfig cfg
125};
Harald Welte96a33b02018-02-04 10:36:22 +0100126
Harald Welte2fa771f2019-05-02 20:13:53 +0200127const integer NUM_GB := 3;
128type record length(NUM_GB) of GbInstance GbInstances;
129type record length(NUM_GB) of NSConfiguration NSConfigurations;
130type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200131
Harald Welte26fbb6e2019-04-14 17:32:46 +0200132const integer NUM_RNC := 1;
133type record of RAN_Configuration RAN_Configurations;
134
Harald Welte96a33b02018-02-04 10:36:22 +0100135type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200136 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200137 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200138 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100139
Harald Welte5ac31492018-02-15 20:39:13 +0100140 var GSUP_Emulation_CT vc_GSUP;
141 var IPA_Emulation_CT vc_GSUP_IPA;
142 /* only to get events from IPA underneath GSUP */
143 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100144
Harald Welteeded9ad2018-02-17 20:57:34 +0100145 var GTP_Emulation_CT vc_GTP;
146
Harald Weltebd194722018-02-16 22:11:08 +0100147 port TELNETasp_PT SGSNVTY;
148
Harald Welte96a33b02018-02-04 10:36:22 +0100149 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200150 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100151};
152
Harald Welte26fbb6e2019-04-14 17:32:46 +0200153type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100154 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100155 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200156 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100157}
158
159type record SGSN_ConnHdlrNetworkPars {
160 boolean expect_ptmsi,
161 boolean expect_auth,
162 boolean expect_ciph
163};
164
165type record BSSGP_ConnHdlrPars {
166 /* IMEI of the simulated ME */
167 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200168 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100169 hexstring imsi,
170 /* MSISDN of the simulated MS (probably unused) */
171 hexstring msisdn,
172 /* P-TMSI allocated to the simulated MS */
173 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100174 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100175 /* TLLI of the simulated MS */
176 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100177 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100178 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200179 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200180 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
181 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100182 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100183 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200184 float t_guard,
185 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200186 SCCP_PAR_Address sccp_addr_local optional,
187 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100188};
189
Alexander Couzens89508702018-07-31 04:16:10 +0200190private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200191 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200192 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
193
194 var RoutingAreaIdentificationV ret := {
195 mccDigit1 := mcc_mnc[0],
196 mccDigit2 := mcc_mnc[1],
197 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200198 mncDigit3 := mcc_mnc[3],
199 mncDigit1 := mcc_mnc[4],
200 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200201 lac := int2oct(cell_id.ra_id.lai.lac, 16),
202 rac := int2oct(cell_id.ra_id.rac, 8)
203 }
204 return ret;
205};
206
Alexander Couzens51114d12018-07-31 18:41:56 +0200207private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
208 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
209 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100210 /* connect lower end of BSSGP emulation with NS upper port */
211 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100212
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200213 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100214 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
215}
216
217private function f_init_gsup(charstring id) runs on test_CT {
218 id := id & "-GSUP";
219 var GsupOps ops := {
220 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
221 };
222
223 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
224 vc_GSUP := GSUP_Emulation_CT.create(id);
225
226 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
227 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
228 /* we use this hack to get events like ASP_IPA_EVENT_UP */
229 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
230
231 vc_GSUP.start(GSUP_Emulation.main(ops, id));
232 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
233
234 /* wait for incoming connection to GSUP port before proceeding */
235 timer T := 10.0;
236 T.start;
237 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700238 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100239 [] T.timeout {
240 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200241 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100242 }
243 }
244}
245
Harald Welteeded9ad2018-02-17 20:57:34 +0100246private function f_init_gtp(charstring id) runs on test_CT {
247 id := id & "-GTP";
248
249 var GtpEmulationCfg gtp_cfg := {
250 gtpc_bind_ip := mp_ggsn_ip,
251 gtpc_bind_port := GTP1C_PORT,
252 gtpu_bind_ip := mp_ggsn_ip,
253 gtpu_bind_port := GTP1U_PORT,
254 sgsn_role := false
255 };
256
257 vc_GTP := GTP_Emulation_CT.create(id);
258 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
259}
260
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200261friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100262 map(self:SGSNVTY, system:SGSNVTY);
263 f_vty_set_prompts(SGSNVTY);
264 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200265 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100266 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
267}
268
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200269private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
270 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200271 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200272 } else {
273 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
274 }
275}
276
Harald Weltebd194722018-02-16 22:11:08 +0100277
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200278/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
279function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200280 var integer i;
281
Harald Welte96a33b02018-02-04 10:36:22 +0100282 if (g_initialized == true) {
283 return;
284 }
285 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100286 g_gb[0].cfg := {
287 nsei := 96,
288 bvci := 196,
289 cell_id := {
290 ra_id := {
291 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100292 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100293 rac := 0
294 },
295 cell_id := 20960
296 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200297 sgsn_role := false,
298 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100299 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200300 g_gb[1].cfg := {
301 nsei := 97,
302 bvci := 210,
303 cell_id := {
304 ra_id := {
305 lai := {
306 mcc_mnc := mcc_mnc, lac := 13200},
307 rac := 0
308 },
309 cell_id := 20961
310 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200311 sgsn_role := false,
312 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200313 };
314 g_gb[2].cfg := {
315 nsei := 98,
316 bvci := 220,
317 cell_id := {
318 ra_id := {
319 lai := {
320 mcc_mnc := mcc_mnc, lac := 13300},
321 rac := 0
322 },
323 cell_id := 20962
324 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200325 sgsn_role := false,
326 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200327 };
Harald Welte96a33b02018-02-04 10:36:22 +0100328
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200329 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200330 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
331 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
332 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200333
Alexander Couzens1552e792019-07-23 20:38:39 +0200334 if (g_ranap_enable) {
335 for (i := 0; i < NUM_RNC; i := i+1) {
336 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
337 f_ran_adapter_start(g_ranap[i]);
338 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200339 }
Harald Welte5ac31492018-02-15 20:39:13 +0100340 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100341 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200342 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100343}
Harald Welte96a33b02018-02-04 10:36:22 +0100344
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200345function f_cleanup() runs on test_CT {
346 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200347 if (g_ranap_enable) {
348 for (i := 0; i < NUM_RNC; i := i+1) {
349 f_ran_adapter_cleanup(g_ranap[i]);
350 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200351 }
352 self.stop;
353}
354
Harald Welte26fbb6e2019-04-14 17:32:46 +0200355private function RncUnitdataCallback(RANAP_PDU ranap)
356runs on RAN_Emulation_CT return template RANAP_PDU {
357 var template RANAP_PDU resp := omit;
358
359 log ("RANAP_RncUnitDataCallback");
360 /* answer all RESET with RESET ACK */
361 if (match(ranap, tr_RANAP_Reset)) {
362 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
363 var CN_DomainIndicator dom;
364 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
365 resp := ts_RANAP_ResetAck(dom);
366 }
367 return resp;
368}
369
370const RanOps RNC_RanOps := {
371 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
372 ranap_unitdata_cb := refers(RncUnitdataCallback),
373 ps_domain := true,
374 decode_dtap := true,
375 role_ms := true,
376 protocol := RAN_PROTOCOL_RANAP,
377 transport := RANAP_TRANSPORT_IuCS,
378 use_osmux := false,
379 sccp_addr_local := omit,
380 sccp_addr_peer := omit
381};
382
Harald Welte5ac31492018-02-15 20:39:13 +0100383type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
384
385/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200386function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100387 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100388runs on test_CT return BSSGP_ConnHdlr {
389 var BSSGP_ConnHdlr vc_conn;
390 var SGSN_ConnHdlrNetworkPars net_pars := {
391 expect_ptmsi := true,
392 expect_auth := true,
393 expect_ciph := false
394 };
395 var BSSGP_ConnHdlrPars pars := {
396 imei := f_gen_imei(imsi_suffix),
397 imsi := f_gen_imsi(imsi_suffix),
398 msisdn := f_gen_msisdn(imsi_suffix),
399 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100400 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100401 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100402 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100403 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200404 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 +0200405 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100406 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100407 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200408 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200409 sccp_addr_local := omit,
410 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100411 };
412
Alexander Couzens1552e792019-07-23 20:38:39 +0200413 if (g_ranap_enable) {
414 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
415 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
416 }
417
Harald Welte5ac31492018-02-15 20:39:13 +0100418 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200419 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200420 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200421 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
422 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200423 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200424 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
425 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200426 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200427 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100428
Harald Welte26fbb6e2019-04-14 17:32:46 +0200429 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200430 if (g_ranap_enable) {
431 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
432 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
433 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200434
Harald Welte5ac31492018-02-15 20:39:13 +0100435 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
436 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
437
Harald Welteeded9ad2018-02-17 20:57:34 +0100438 connect(vc_conn:GTP, vc_GTP:CLIENT);
439 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
440
Harald Welte5ac31492018-02-15 20:39:13 +0100441 vc_conn.start(f_handler_init(fn, id, pars));
442 return vc_conn;
443}
444
Harald Welte62e29582018-02-16 21:17:11 +0100445private altstep as_Tguard() runs on BSSGP_ConnHdlr {
446 [] g_Tguard.timeout {
447 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200448 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100449 }
450}
451
Harald Welte5ac31492018-02-15 20:39:13 +0100452/* first function called in every ConnHdlr */
453private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
454runs on BSSGP_ConnHdlr {
455 /* do some common stuff like setting up g_pars */
456 g_pars := pars;
457
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200458 llc := f_llc_create(false);
459
Harald Welte5ac31492018-02-15 20:39:13 +0100460 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200461 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100462 /* tell GSUP dispatcher to send this IMSI to us */
463 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100464 /* tell GTP dispatcher to send this IMSI to us */
465 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100466
Harald Welte62e29582018-02-16 21:17:11 +0100467 g_Tguard.start(pars.t_guard);
468 activate(as_Tguard());
469
Harald Welte5ac31492018-02-15 20:39:13 +0100470 /* call the user-supplied test case function */
471 fn.apply(id);
472 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100473}
474
475/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100476 * Detach without Attach
477 * SM procedures without attach / RAU
478 * ATTACH / RAU
479 ** with / without authentication
480 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100481 * re-transmissions of LLC frames
482 * PDP Context activation
483 ** with different GGSN config in SGSN VTY
484 ** with different PDP context type (v4/v6/v46)
485 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100486 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100487 */
488
489testcase TC_wait_ns_up() runs on test_CT {
490 f_init();
491 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200492 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100493}
494
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200495friend function is_gb(integer ran_index) return boolean {
496 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200497}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200498friend function is_iu(integer ran_index) return boolean {
499 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200500}
501
Alexander Couzens0507ec32019-09-15 22:41:22 +0200502function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200503 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200504 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 +0200505}
506
Alexander Couzens0507ec32019-09-15 22:41:22 +0200507private 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 +0200508 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
509 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
510 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200511 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200512}
513
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200514/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
515function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
516 log("Sending InitialUE: ", l3_mo);
517 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
518 var RANAP_PDU ranap;
519 var LAI lai := {
520 pLMNidentity := '62F224'O,
521 lAC := '1234'O,
522 iE_Extensions := omit
523 };
524 var SAI sai := {
525 pLMNidentity := lai.pLMNidentity,
526 lAC := lai.lAC,
527 sAC := '0000'O, /* FIXME */
528 iE_Extensions := omit
529 };
530 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
531 var GlobalRNC_ID grnc_id := {
532 pLMNidentity := lai.pLMNidentity,
533 rNC_ID := 2342 /* FIXME */
534 };
535
536 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
537 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
538 alt {
539 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
540 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
541 setverdict(fail, "DISC.ind from SCCP");
542 mtc.stop;
543 }
544 }
545}
546
547/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200548function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
549 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200550 if (g_pars.rnc_send_initial_ue) {
551 g_pars.rnc_send_initial_ue := false;
552 f_send_l3_initial_ue(l3_mo);
553 } else {
554 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
555 }
556 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200557 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200558 }
559}
560
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200561altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700562 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200563 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100564 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200565 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100566 repeat;
567 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200568 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200569 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200570 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200571 repeat;
572 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200573 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100574 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200575 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200576 repeat;
577 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200578 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200579 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200580 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100581 repeat;
582 }
583}
Harald Welte96a33b02018-02-04 10:36:22 +0100584
Harald Welteca362462019-05-02 20:11:21 +0200585/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200586function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200587runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200588 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200589 var PDU_L3_SGSN_MS l3_mt;
590 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200591 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
592 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200593 l3_mt := mt.dtap;
594 }
Harald Welteca362462019-05-02 20:11:21 +0200595 }
596 return l3_mt;
597}
598
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200599/* perform GMM authentication (if expected).
600 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
601 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200602function 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 +0100603 var PDU_L3_MS_SGSN l3_mo;
604 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200605 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100606 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200607 var GSUP_IE auth_tuple;
608 var template AuthenticationParameterAUTNTLV autn;
609
610 if (umts_aka_challenge) {
611 g_pars.vec := f_gen_auth_vec_3g();
612 autn := {
613 elementIdentifier := '28'O,
614 lengthIndicator := lengthof(g_pars.vec.autn),
615 autnValue := g_pars.vec.autn
616 };
617
618 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
619 g_pars.vec.sres,
620 g_pars.vec.kc,
621 g_pars.vec.ik,
622 g_pars.vec.ck,
623 g_pars.vec.autn,
624 g_pars.vec.res));
625 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
626 } else {
627 g_pars.vec := f_gen_auth_vec_2g();
628 autn := omit;
629 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
630 g_pars.vec.sres,
631 g_pars.vec.kc));
632 log("GSUP sends only 2G auth tuple", auth_tuple);
633 }
Harald Welteca362462019-05-02 20:11:21 +0200634
Harald Welte5ac31492018-02-15 20:39:13 +0100635 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
636 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200637
638 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
639 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200640 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100641 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200642 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
643
644 if (umts_aka_challenge and not force_gsm_sres) {
645 /* set UMTS response instead */
646 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
647 valueField := substr(g_pars.vec.res, 0, 4)
648 };
649 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
650 elementIdentifier := '21'O,
651 lengthIndicator := lengthof(g_pars.vec.res) - 4,
652 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
653 };
654 }
655
656 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100657 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
658 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
659 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
660 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
661 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200663
664 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200665 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200666 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
667 key_sts := ?)) {
668 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
669 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200670 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200671 }
672 }
Harald Welte76dee092018-02-16 22:12:59 +0100673 } else {
674 /* wait for identity procedure */
675 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100676 }
Harald Welte76dee092018-02-16 22:12:59 +0100677
Harald Welte5ac31492018-02-15 20:39:13 +0100678 deactivate(di);
679}
680
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200681function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100682 g_pars.p_tmsi := p_tmsi;
683 /* update TLLI */
684 g_pars.tlli_old := g_pars.tlli;
685 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100686 if (is_gb(ran_index)) {
687 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
688 }
Harald Weltef70997d2018-02-17 10:11:19 +0100689}
690
Harald Welte04683d02018-02-16 22:43:45 +0100691function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
692 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100693 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200694 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100695 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200696 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200697 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100698 }
Harald Welte04683d02018-02-16 22:43:45 +0100699 g_pars.ra := aa.routingAreaIdentification;
700 if (ispresent(aa.allocatedPTMSI)) {
701 if (not g_pars.net.expect_ptmsi) {
702 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200703 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100704 }
Harald Weltef70997d2018-02-17 10:11:19 +0100705 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100706 }
707 if (ispresent(aa.msIdentity)) {
708 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200709 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100710 }
711 /* P-TMSI.sig */
712 if (ispresent(aa.ptmsiSignature)) {
713 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
714 }
715 /* updateTimer */
716 // aa.readyTimer
717 /* T3302, T3319, T3323, T3312_ext, T3324 */
718}
719
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200720function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100721 /* mandatory IE */
722 g_pars.ra := ra.routingAreaId;
723 if (ispresent(ra.allocatedPTMSI)) {
724 if (not g_pars.net.expect_ptmsi) {
725 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200726 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100727 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200728 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100729 }
730 if (ispresent(ra.msIdentity)) {
731 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200732 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100733 }
734 /* P-TMSI.sig */
735 if (ispresent(ra.ptmsiSignature)) {
736 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
737 }
738 /* updateTimer */
739 // aa.readyTimer
740 /* T3302, T3319, T3323, T3312_ext, T3324 */
741}
742
743
Harald Welte5a4fa042018-02-16 20:59:21 +0100744function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
745 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
746}
747
Harald Welte23178c52018-02-17 09:36:33 +0100748/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700749private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100750 if (ispresent(g_pars.p_tmsi)) {
751 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
752 } else {
753 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
754 }
755}
756
Harald Welte311ec272018-02-17 09:40:03 +0100757private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100758 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100759 /* Expect MSC to perform LU with HLR */
760 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100761 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
762 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
763 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100764 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
765 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
766}
767
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200768friend 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 +0100769 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200770 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 +0200771 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100772
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200773 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
774 * 3G auth vectors */
775 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
776 /* The thing is, if the solSACapability is 'omit', then the
777 * revisionLevelIndicatior is at the wrong place! */
778 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
779
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200780 f_send_l3(attach_req, ran_index);
781 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200782 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100783 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100784
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200785 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200786 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
787
Harald Welte04683d02018-02-16 22:43:45 +0100788 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200789 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200790
791 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200792 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200793 as_iu_release_compl_disc();
794 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200795
796 /* Race condition
797 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
798 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
799 * arrived before it. This results in a test case failure.
800 * Delay execution by 50 ms
801 */
802 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200803}
804
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200805friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
806 timer T := 5.0;
807 var PDU_BSSGP rx_pdu;
808 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
809 T.start;
810 alt {
811 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
812 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
813 }
814 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
815 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
816 mtc.stop;
817 }
818 [] T.timeout {
819 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
820 mtc.stop;
821 }
822 }
823 return '00'O;
824}
825
826friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
827 timer T := 5.0;
828 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
829 T.start;
830 alt {
831 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
832 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
833?)) {
834 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
835 mtc.stop;
836 }
837 [] T.timeout {
838 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
839 mtc.stop;
840 }
841 }
842}
843
844
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200845private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
846 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100847 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100848}
849
850testcase TC_attach() runs on test_CT {
851 var BSSGP_ConnHdlr vc_conn;
852 f_init();
853 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200854 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100855 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200856 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100857}
858
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100859testcase TC_attach_mnc3() runs on test_CT {
860 var BSSGP_ConnHdlr vc_conn;
861 f_init('023042'H);
862 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200863 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100864 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200865 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100866}
867
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200868private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
869 f_gmm_attach(true, false);
870 setverdict(pass);
871}
872testcase TC_attach_umts_aka_umts_res() runs on test_CT {
873 var BSSGP_ConnHdlr vc_conn;
874 f_init();
875 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200876 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200877 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200878 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200879}
880
881private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
882 f_gmm_attach(true, true);
883 setverdict(pass);
884}
885testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
886 var BSSGP_ConnHdlr vc_conn;
887 f_init();
888 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200889 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200890 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200891 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200892}
893
Harald Welte5b7c8122018-02-16 21:48:17 +0100894/* MS never responds to ID REQ, expect ATTACH REJECT */
895private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100896 var RoutingAreaIdentificationV old_ra := f_random_RAI();
897
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200898 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100899 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200900 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100901 /* don't send ID Response */
902 repeat;
903 }
Harald Welte955aa942019-05-03 01:29:29 +0200904 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100905 setverdict(pass);
906 }
Harald Welte955aa942019-05-03 01:29:29 +0200907 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100908 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200909 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100910 }
911 }
912}
913testcase TC_attach_auth_id_timeout() runs on test_CT {
914 var BSSGP_ConnHdlr vc_conn;
915 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200916 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 +0100917 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200918 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100919}
920
921/* HLR never responds to SAI REQ, expect ATTACH REJECT */
922private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100923 var RoutingAreaIdentificationV old_ra := f_random_RAI();
924
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200925 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100926 alt {
927 [] as_mm_identity();
928 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
929 }
930 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200931 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100932 setverdict(pass);
933}
934testcase TC_attach_auth_sai_timeout() runs on test_CT {
935 var BSSGP_ConnHdlr vc_conn;
936 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200937 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100938 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200939 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100940}
941
Harald Weltefe253882018-02-17 09:25:00 +0100942/* HLR rejects SAI, expect ATTACH REJECT */
943private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100944 var RoutingAreaIdentificationV old_ra := f_random_RAI();
945
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200946 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100947 alt {
948 [] as_mm_identity();
949 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
950 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
951 }
952 }
Harald Welte955aa942019-05-03 01:29:29 +0200953 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100954 setverdict(pass);
955}
956testcase TC_attach_auth_sai_reject() runs on test_CT {
957 var BSSGP_ConnHdlr vc_conn;
958 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200959 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100960 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200961 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100962}
963
Harald Welte5b7c8122018-02-16 21:48:17 +0100964/* HLR never responds to UL REQ, expect ATTACH REJECT */
965private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200966 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100967 var RoutingAreaIdentificationV old_ra := f_random_RAI();
968
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200969 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100970 f_gmm_auth();
971 /* Expect MSC to perform LU with HLR */
972 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
973 /* Never follow-up with ISD_REQ or UL_RES */
974 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200975 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100976 setverdict(pass);
977 }
Harald Welte955aa942019-05-03 01:29:29 +0200978 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
979 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100980 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200981 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100982 }
983 }
984}
985testcase TC_attach_gsup_lu_timeout() runs on test_CT {
986 var BSSGP_ConnHdlr vc_conn;
987 f_init();
988 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200989 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100990 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200991 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100992}
993
Harald Welteb7c14e92018-02-17 09:29:16 +0100994/* HLR rejects UL REQ, expect ATTACH REJECT */
995private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200996 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100997 var RoutingAreaIdentificationV old_ra := f_random_RAI();
998
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200999 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001000 f_gmm_auth();
1001 /* Expect MSC to perform LU with HLR */
1002 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1003 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1004 }
1005 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001006 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001007 setverdict(pass);
1008 }
Harald Welte955aa942019-05-03 01:29:29 +02001009 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1010 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001011 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001012 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001013 }
1014 }
1015}
1016testcase TC_attach_gsup_lu_reject() runs on test_CT {
1017 var BSSGP_ConnHdlr vc_conn;
1018 f_init();
1019 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001020 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001021 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001022 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001023}
1024
1025
Harald Welte3823e2e2018-02-16 21:53:48 +01001026/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1027private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001028 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001029 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1030
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001031 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001032 f_gmm_auth();
1033 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001034 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001035
Harald Welte955aa942019-05-03 01:29:29 +02001036 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1037 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001038 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001039 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001040 setverdict(pass);
1041}
Harald Welte3823e2e2018-02-16 21:53:48 +01001042testcase TC_attach_combined() runs on test_CT {
1043 var BSSGP_ConnHdlr vc_conn;
1044 f_init();
1045 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001046 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001047 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001048 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001049}
1050
Harald Welte76dee092018-02-16 22:12:59 +01001051/* Attempt of GPRS ATTACH in 'accept all' mode */
1052private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001053 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001054 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1055
1056 g_pars.net.expect_auth := false;
1057
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001058 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001059 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001060 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1061 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001062 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001063 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001064 setverdict(pass);
1065}
1066testcase TC_attach_accept_all() runs on test_CT {
1067 var BSSGP_ConnHdlr vc_conn;
1068 f_init();
1069 f_sleep(1.0);
1070 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001071 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001072 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001073 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001074}
Harald Welte5b7c8122018-02-16 21:48:17 +01001075
Harald Welteb2124b22018-02-16 22:26:56 +01001076/* Attempt of GPRS ATTACH in 'accept all' mode */
1077private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001078 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1079
1080 /* Simulate a foreign IMSI */
1081 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001082 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001083
1084 g_pars.net.expect_auth := false;
1085
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001086 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001087 alt {
1088 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001089 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001090 setverdict(pass);
1091 }
Harald Welte955aa942019-05-03 01:29:29 +02001092 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001093 setverdict(pass);
1094 }
Harald Welte955aa942019-05-03 01:29:29 +02001095 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001096 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001097 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001098 }
Harald Welteb2124b22018-02-16 22:26:56 +01001099 }
1100}
1101testcase TC_attach_closed() runs on test_CT {
1102 var BSSGP_ConnHdlr vc_conn;
1103 f_init();
1104 f_sleep(1.0);
1105 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1106 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001107 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001108 vc_conn.done;
1109 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001110 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001111 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001112 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001113}
1114
Harald Welte04683d02018-02-16 22:43:45 +01001115/* Routing Area Update from Unknown TLLI -> REJECT */
1116private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001117 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1118
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001119 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 +01001120 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001121 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001122 setverdict(pass);
1123 }
1124 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001125 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001126 }
1127}
1128testcase TC_rau_unknown() runs on test_CT {
1129 var BSSGP_ConnHdlr vc_conn;
1130 f_init();
1131 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001132 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001133 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001134 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001135}
1136
Harald Welte91636de2018-02-17 10:16:14 +01001137private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001138 /* first perform regular attach */
1139 f_TC_attach(id);
1140
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001141 f_routing_area_update(g_pars.ra);
1142
Harald Welte91636de2018-02-17 10:16:14 +01001143}
1144testcase TC_attach_rau() runs on test_CT {
1145 var BSSGP_ConnHdlr vc_conn;
1146 f_init();
1147 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001148 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001149 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001150 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001151}
Harald Welte04683d02018-02-16 22:43:45 +01001152
Harald Welte6abb9fe2018-02-17 15:24:48 +01001153/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001154function 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 +02001155 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001156 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001157 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001158 if (expect_purge) {
1159 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1160 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1161 }
1162 T.start;
1163 alt {
1164 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1165 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001166 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001167 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001168 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001169 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001170 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001171 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001172 /* TODO: check if any PDP contexts are deactivated on network side? */
1173 }
1174 [power_off] T.timeout {
1175 setverdict(pass);
1176 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001177 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001178 g_pars.ra := omit;
1179 setverdict(pass);
1180 /* TODO: check if any PDP contexts are deactivated on network side? */
1181 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001182 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001183 if (power_off) {
1184 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1185 } else {
1186 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1187 }
1188 mtc.stop;
1189 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001190 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001191 }
1192}
1193
1194/* IMSI DETACH (non-power-off) for unknown TLLI */
1195private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1196 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1197}
1198testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1199 var BSSGP_ConnHdlr vc_conn;
1200 f_init();
1201 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001202 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001203 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001204 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001205}
1206
1207/* IMSI DETACH (power-off) for unknown TLLI */
1208private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1209 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1210}
1211testcase TC_detach_unknown_poweroff() runs on test_CT {
1212 var BSSGP_ConnHdlr vc_conn;
1213 f_init();
1214 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001215 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001216 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001217 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001218}
1219
1220/* IMSI DETACH (non-power-off) for known TLLI */
1221private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1222 /* first perform regular attach */
1223 f_TC_attach(id);
1224
1225 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1226}
1227testcase TC_detach_nopoweroff() runs on test_CT {
1228 var BSSGP_ConnHdlr vc_conn;
1229 f_init();
1230 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001231 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001232 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001233 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001234}
1235
1236/* IMSI DETACH (power-off) for known TLLI */
1237private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1238 /* first perform regular attach */
1239 f_TC_attach(id);
1240
1241 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1242}
1243testcase TC_detach_poweroff() runs on test_CT {
1244 var BSSGP_ConnHdlr vc_conn;
1245 f_init();
1246 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001247 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001248 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001249 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001250}
1251
Harald Welteeded9ad2018-02-17 20:57:34 +01001252type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001253 BIT3 tid, /* L3 Transaction ID */
1254 BIT4 nsapi, /* SNDCP NSAPI */
1255 BIT4 sapi, /* LLC SAPI */
1256 QoSV qos, /* QoS parameters */
1257 PDPAddressV addr, /* IP address */
1258 octetstring apn optional, /* APN name */
1259 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1260 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001261 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001262 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001263
Harald Welte822f9102018-02-18 20:39:06 +01001264 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1265 OCT4 ggsn_tei_u, /* GGSN TEI User */
1266 octetstring ggsn_ip_c, /* GGSN IP Control */
1267 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001268 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001269
Harald Welte822f9102018-02-18 20:39:06 +01001270 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1271 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1272 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1273 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001274};
1275
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001276
1277private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1278 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1279 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1280 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1281 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1282 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1283 f_gtp_register_teid(apars.ggsn_tei_c);
1284 f_gtp_register_teid(apars.ggsn_tei_u);
1285}
1286
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001287function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001288runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001289 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1290 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001291 var template Recovery_gtpc recovery := omit;
1292
1293 if (send_recovery) {
1294 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1295 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001296
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001297 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 +02001298 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001299 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1300 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1301 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1302 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1303 apars.sgsn_tei_c, apars.gtp_resp_cause,
1304 apars.ggsn_tei_c, apars.ggsn_tei_u,
1305 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001306 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1307 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001308 }
1309 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001310 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001311 setverdict(pass);
1312 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001313 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001314 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001315 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001316 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001317 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001318 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001319 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001320 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001321 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001322 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1323 mtc.stop;
1324 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001325 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001326 setverdict(pass);
1327 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001328 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001329 }
1330}
1331
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001332function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001333runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001334 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1335 var Gtp1cUnitdata g_ud;
1336
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001337 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001338 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1339 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001340 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001341 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1342 }
1343 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001344 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001345 setverdict(pass);
1346 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001347 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001348 }
1349}
1350
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001351function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001352runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001353 var Gtp1cUnitdata g_ud;
1354 var integer seq_nr := 23;
1355 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1356
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001357 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001358 if (error_ind) {
1359 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1360 } else {
1361 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1362 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001363
1364 timer T := 5.0;
1365 T.start;
1366
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001367 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001368 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1369 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001370 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001371 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1372 repeat;
1373 }
1374 [] T.timeout {
1375 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1376 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001377 }
1378}
1379
Harald Welte6f203162018-02-18 22:04:55 +01001380
Harald Welteeded9ad2018-02-17 20:57:34 +01001381/* Table 10.5.156/3GPP TS 24.008 */
1382template (value) QoSV t_QosDefault := {
1383 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1384 delayClass := '100'B, /* best effort */
1385 spare1 := '00'B,
1386 precedenceClass := '010'B, /* normal */
1387 spare2 := '0'B,
1388 peakThroughput := '0000'B, /* subscribed */
1389 meanThroughput := '00000'B, /* subscribed */
1390 spare3 := '000'B,
1391 deliverErroneusSDU := omit,
1392 deliveryOrder := omit,
1393 trafficClass := omit,
1394 maxSDUSize := omit,
1395 maxBitrateUplink := omit,
1396 maxBitrateDownlink := omit,
1397 sduErrorRatio := omit,
1398 residualBER := omit,
1399 trafficHandlingPriority := omit,
1400 transferDelay := omit,
1401 guaranteedBitRateUplink := omit,
1402 guaranteedBitRateDownlink := omit,
1403 sourceStatisticsDescriptor := omit,
1404 signallingIndication := omit,
1405 spare4 := omit,
1406 maxBitrateDownlinkExt := omit,
1407 guaranteedBitRateDownlinkExt := omit,
1408 maxBitrateUplinkExt := omit,
1409 guaranteedBitRateUplinkExt := omit,
1410 maxBitrateDownlinkExt2 := omit,
1411 guaranteedBitRateDownlinkExt2 := omit,
1412 maxBitrateUplinkExt2 := omit,
1413 guaranteedBitRateUplinkExt2 := omit
1414}
1415
1416/* 10.5.6.4 / 3GPP TS 24.008 */
1417template (value) PDPAddressV t_AddrIPv4dyn := {
1418 pdpTypeOrg := '0001'B, /* IETF */
1419 spare := '0000'B,
1420 pdpTypeNum := '21'O, /* IPv4 */
1421 addressInfo := omit
1422}
1423template (value) PDPAddressV t_AddrIPv6dyn := {
1424 pdpTypeOrg := '0001'B, /* IETF */
1425 spare := '0000'B,
1426 pdpTypeNum := '53'O, /* IPv6 */
1427 addressInfo := omit
1428}
1429
Harald Welte37692d82018-02-18 15:21:34 +01001430template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001431 tid := '000'B,
1432 nsapi := '0101'B, /* < 5 are reserved */
1433 sapi := '0011'B, /* 3/5/9/11 */
1434 qos := t_QosDefault,
1435 addr := t_AddrIPv4dyn,
1436 apn := omit,
1437 pco := omit,
1438 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001439 gtp_resp_cause := int2oct(128, 1),
1440 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001441
1442 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001443 ggsn_tei_c := f_rnd_octstring(4),
1444 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001445 ggsn_ip_c := f_inet_addr(ggsn_ip),
1446 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001447 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001448
Harald Welteeded9ad2018-02-17 20:57:34 +01001449 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001450 sgsn_tei_u := omit,
1451 sgsn_ip_c := omit,
1452 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001453}
1454
Harald Welte37692d82018-02-18 15:21:34 +01001455template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1456 connId := 1,
1457 remName := f_inet_ntoa(ip),
1458 remPort := GTP1U_PORT
1459}
1460
1461template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1462 connId := 1,
1463 remName := f_inet_ntoa(ip),
1464 remPort := GTP1C_PORT
1465}
1466
1467private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1468 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1469 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1470}
1471
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001472private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1473 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001474 repeat;
1475 }
1476}
1477
1478template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1479 pDU_SN_UNITDATA := {
1480 nsapi := nsapi,
1481 moreBit := ?,
1482 snPduType := '1'B,
1483 firstSegmentIndicator := ?,
1484 spareBit := ?,
1485 pcomp := ?,
1486 dcomp := ?,
1487 npduNumber := ?,
1488 segmentNumber := ?,
1489 npduNumberContinued := ?,
1490 dataSegmentSnUnitdataPdu := payload
1491 }
1492}
1493
1494/* simple case: single segment, no compression */
1495template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1496 pDU_SN_UNITDATA := {
1497 nsapi := nsapi,
1498 moreBit := '0'B,
1499 snPduType := '1'B,
1500 firstSegmentIndicator := '1'B,
1501 spareBit := '0'B,
1502 pcomp := '0000'B,
1503 dcomp := '0000'B,
1504 npduNumber := '0000'B,
1505 segmentNumber := '0000'B,
1506 npduNumberContinued := '00'O,
1507 dataSegmentSnUnitdataPdu := payload
1508 }
1509}
1510
1511/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001512private function f_gtpu_xceive_mt(inout PdpActPars apars, octetstring payload, integer ran_index := 0, boolean expect_fwd := true)
Harald Weltef7191672019-05-02 20:37:23 +02001513runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001514 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001515 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1516 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001517 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001518 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1519 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001520 [] as_xid(apars, ran_index);
1521 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001522 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1523 [expect_fwd] T.timeout {
1524 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1525 mtc.stop;
1526 }
1527 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1528 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1529 mtc.stop;
1530 }
1531 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001532 }
1533}
1534
Harald Welte64d6b512020-06-17 16:42:00 +02001535/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001536private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001537runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001538 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1539 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1540 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001541 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001542 /* Expect PDU via GTP from SGSN on simulated GGSN */
1543 alt {
1544 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1545 }
1546}
1547
Harald Welteeded9ad2018-02-17 20:57:34 +01001548private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001549 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001550
1551 /* first perform regular attach */
1552 f_TC_attach(id);
1553
1554 f_pdp_ctx_act(apars);
1555}
1556testcase TC_attach_pdp_act() runs on test_CT {
1557 var BSSGP_ConnHdlr vc_conn;
1558 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001559 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001560 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001561 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001562}
Harald Welteb2124b22018-02-16 22:26:56 +01001563
Harald Welte835b15f2018-02-18 14:39:11 +01001564/* PDP Context activation for not-attached subscriber; expect fail */
1565private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001566 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001567 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 +01001568 apars.apn, apars.pco));
1569 alt {
1570 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001571 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001572 setverdict(pass);
1573 }
1574 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1575 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001576 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001577 }
Harald Welte955aa942019-05-03 01:29:29 +02001578 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001579 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001580 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001581 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001582 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001583 }
1584}
1585testcase TC_pdp_act_unattached() runs on test_CT {
1586 var BSSGP_ConnHdlr vc_conn;
1587 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001588 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001589 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001590 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001591}
1592
Harald Welte37692d82018-02-18 15:21:34 +01001593/* ATTACH + PDP CTX ACT + user plane traffic */
1594private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1595 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1596
1597 /* first perform regular attach */
1598 f_TC_attach(id);
1599 /* then activate PDP context */
1600 f_pdp_ctx_act(apars);
1601 /* then transceive a downlink PDU */
1602 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1603 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1604}
1605testcase TC_attach_pdp_act_user() runs on test_CT {
1606 var BSSGP_ConnHdlr vc_conn;
1607 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001608 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001609 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001610 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001611}
1612
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001613/* ATTACH + PDP CTX ACT; reject from GGSN */
1614private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1615 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1616
1617 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1618 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1619
1620 /* first perform regular attach */
1621 f_TC_attach(id);
1622 /* then activate PDP context */
1623 f_pdp_ctx_act(apars);
1624}
1625testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1626 var BSSGP_ConnHdlr vc_conn;
1627 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001628 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001629 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001630 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001631}
Harald Welte835b15f2018-02-18 14:39:11 +01001632
Harald Welte6f203162018-02-18 22:04:55 +01001633/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1634private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1635 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1636
1637 /* first perform regular attach */
1638 f_TC_attach(id);
1639 /* then activate PDP context */
1640 f_pdp_ctx_act(apars);
1641 /* then transceive a downlink PDU */
1642 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1643 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1644
1645 f_pdp_ctx_deact_mo(apars, '00'O);
1646}
1647testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1648 var BSSGP_ConnHdlr vc_conn;
1649 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001650 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 +01001651 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001652 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001653}
1654
Harald Welte57b9b7f2018-02-18 22:28:13 +01001655/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1656private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1657 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1658
1659 /* first perform regular attach */
1660 f_TC_attach(id);
1661 /* then activate PDP context */
1662 f_pdp_ctx_act(apars);
1663 /* then transceive a downlink PDU */
1664 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1665 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1666
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001667 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001668}
1669testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1670 var BSSGP_ConnHdlr vc_conn;
1671 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001672 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 +01001673 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001674 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001675}
1676
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001677/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1678private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1679 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1680 var Gtp1cUnitdata g_ud;
1681 var integer i;
1682 var OCT1 cause_regular_deact := '24'O;
1683
1684 /* first perform regular attach + PDP context act */
1685 f_TC_attach(id);
1686 f_pdp_ctx_act(apars);
1687
1688 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1689 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1690
1691 for (i := 0; i < 2; i := i+1) {
1692 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1693 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1694 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1695 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1696 }
1697 }
1698
1699 alt {
1700 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1701 setverdict(pass);
1702 }
1703 [] as_xid(apars, 0);
1704 }
1705
1706 /* Make sure second DeactPdpAccept is sent: */
1707 timer T := 2.0;
1708 T.start;
1709 alt {
1710 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1711 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1712 }
1713 [] T.timeout {
1714 setverdict(pass);
1715 }
1716 }
1717
1718 setverdict(pass);
1719}
1720testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1721 var BSSGP_ConnHdlr vc_conn;
1722 f_init();
1723 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1724 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001725 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001726}
1727
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001728/* ATTACH + ATTACH (2nd) */
1729private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1730 g_pars.t_guard := 5.0;
1731
1732 /* first perform regular attach */
1733 f_TC_attach(id);
1734
1735 /* second to perform regular attach */
1736 f_TC_attach(id);
1737}
1738
1739
1740testcase TC_attach_second_attempt() runs on test_CT {
1741 var BSSGP_ConnHdlr vc_conn;
1742 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001743 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001744 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001745 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001746}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001747
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001748private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1749 var Gtp1cUnitdata g_ud;
1750 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1751 var integer seq_nr;
1752
1753 /* first perform regular attach */
1754 f_TC_attach(id);
1755 /* then activate PDP context */
1756 f_pdp_ctx_act(apars);
1757
1758 /* Wait to receive first echo request and send initial Restart counter */
1759 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1760 BSSGP[0].clear;
1761 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1762 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1763 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1764 }
1765
1766 /* At some point next echo request not answered will timeout and SGSN
1767 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1768 timer T := 3.0 * 6.0 + 16.0;
1769 T.start;
1770 alt {
1771 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1772 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1773 setverdict(pass);
1774 }
1775 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1776 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1777 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1778 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1779 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1780 repeat;
1781 }
1782 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1783 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1784 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1785 repeat;
1786 }
1787 [] T.timeout {
1788 setverdict(fail, "BSSGP DeactPdpReq not received");
1789 mtc.stop;
1790 }
1791 [] as_xid(apars);
1792 }
1793 T.stop
1794
1795 setverdict(pass);
1796}
1797/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1798testcase TC_attach_echo_timeout() runs on test_CT {
1799 var BSSGP_ConnHdlr vc_conn;
1800 g_use_echo := true;
1801 f_init();
1802 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1803 vc_conn.done;
1804 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001805 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001806}
1807
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001808private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001809 var Gtp1cUnitdata g_ud;
1810 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1811
1812 /* first perform regular attach */
1813 f_TC_attach(id);
1814 /* Activate a pdp context against the GGSN */
1815 f_pdp_ctx_act(apars);
1816 /* Wait to receive first echo request and send initial Restart counter */
1817 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1818 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1819 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1820 }
1821 /* Wait to receive second echo request and send incremented Restart
1822 counter. This will fake a restarted GGSN, and pdp ctx allocated
1823 should be released by SGSN */
1824 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1825 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1826 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1827 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1828 }
1829 var OCT1 cause_network_failure := int2oct(38, 1)
1830 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001831 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001832 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001833 setverdict(pass);
1834 }
1835 [] as_xid(apars);
1836 }
1837 setverdict(pass);
1838}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001839/* ATTACH + trigger Recovery procedure through EchoResp */
1840testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001841 var BSSGP_ConnHdlr vc_conn;
1842 g_use_echo := true
1843 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001844 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 +02001845 vc_conn.done;
1846 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001847 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001848}
1849
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001850private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1851 var Gtp1cUnitdata g_ud;
1852 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1853 var integer seq_nr := 23;
1854 var GtpPeer peer;
1855 /* first perform regular attach */
1856 f_TC_attach(id);
1857
1858 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1859 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1860 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1861 f_pdp_ctx_act(apars, true);
1862
1863 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1864/* received. */
1865 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1866
1867 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1868 would be great to have an active pdp context here before triggering
1869 Recovery, and making sure the the DEACT request is sent by the SGSN.
1870 */
1871
1872 /* Activate a pdp context against the GGSN, send incremented Recovery
1873 IE. This should trigger the recovery path, but still this specific
1874 CTX activation should work. */
1875 apars.exp_rej_cause := omit; /* default value for tests */
1876 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1877 f_pdp_ctx_act(apars, true);
1878
1879 setverdict(pass);
1880}
1881/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1882testcase TC_attach_restart_ctr_create() runs on test_CT {
1883 var BSSGP_ConnHdlr vc_conn;
1884 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001885 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 +02001886 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001887 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001888}
1889
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001890/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1891private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1892 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1893 var integer seq_nr := 23;
1894 var GtpPeer peer;
1895 var integer i;
1896
1897 /* first perform regular attach */
1898 f_TC_attach(id);
1899 /* then activate PDP context */
1900 f_pdp_ctx_act(apars);
1901
Alexander Couzens0e510e62018-07-28 23:06:00 +02001902 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001903 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1904 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1905
1906 for (i := 0; i < 5; i := i+1) {
1907 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001908 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001909 [] as_xid(apars);
1910 }
1911 }
1912
1913 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1914
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001915 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001916 setverdict(pass);
1917}
1918testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1919 var BSSGP_ConnHdlr vc_conn;
1920 f_init();
1921 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001922 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 +02001923 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001924 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001925}
1926
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001927/* ATTACH + PDP CTX ACT dropped + retrans */
1928private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1929 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1930 var Gtp1cUnitdata g_ud_first, g_ud_second;
1931 /* first perform regular attach */
1932 f_TC_attach(id);
1933
1934 /* then activate PDP context on the Gb side */
1935 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1936 apars.apn, apars.pco), 0);
1937
1938 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1939 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1940 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1941 if (g_ud_first != g_ud_second) {
1942 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1943 mtc.stop;
1944 }
1945 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1946 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1947 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1948 apars.sgsn_tei_c, apars.gtp_resp_cause,
1949 apars.ggsn_tei_c, apars.ggsn_tei_u,
1950 apars.nsapi,
1951 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1952 omit, omit));
1953 }
Harald Welte955aa942019-05-03 01:29:29 +02001954 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001955
1956 /* Now the same with Deact */
1957 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1958 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1959 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1960 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1961 if (g_ud_first != g_ud_second) {
1962 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1963 mtc.stop;
1964 }
1965 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1966 BSSGP[0].clear;
1967 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1968 }
1969 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001970 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001971 setverdict(pass);
1972 }
1973 [] as_xid(apars, 0);
1974 }
1975
1976 setverdict(pass);
1977}
1978testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1979 var BSSGP_ConnHdlr vc_conn;
1980 f_init();
1981 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1982 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001983 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001984}
1985
1986/* Test that SGSN GTP response retransmit queue works fine */
1987private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1988 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1989 var integer seq_nr := 23;
1990 var Gtp1cUnitdata g_ud_first, g_ud_second;
1991 var template Gtp1cUnitdata g_delete_req;
1992 /* first perform regular attach + PDP context act */
1993 f_TC_attach(id);
1994 f_pdp_ctx_act(apars);
1995
1996 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1997 BSSGP[0].clear;
1998 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1999 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2000 GTP.send(g_delete_req);
2001 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002002 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002003 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2004 }
2005 [] as_xid(apars, 0);
2006 }
2007 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2008 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2009 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2010 mtc.stop;
2011 }
2012 };
2013
2014 /* Send duplicate DeleteCtxReq */
2015 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2016 GTP.send(g_delete_req);
2017 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2018 if (g_ud_first != g_ud_second) {
2019 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2020 mtc.stop;
2021 }
2022 }
2023
2024 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2025 * is handled differently by SGSN (expect "non-existent" cause) */
2026 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2027 GTP.send(g_delete_req);
2028 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2029 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2030 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2031 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2032 mtc.stop;
2033 }
2034 }
2035
2036 setverdict(pass);
2037}
2038testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2039 var BSSGP_ConnHdlr vc_conn;
2040 f_init();
2041 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2042 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002043 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002044}
2045
Alexander Couzens5e307b42018-05-22 18:12:20 +02002046private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2047 /* MS: perform regular attach */
2048 f_TC_attach(id);
2049
2050 /* HLR: cancel the location request */
2051 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2052 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002053
2054 /* ensure no Detach Request got received */
2055 timer T := 5.0;
2056 T.start;
2057 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002058 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002059 T.stop;
2060 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002061 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002062 }
2063 [] T.timeout {
2064 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002065 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002066 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002067 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002068 repeat;
2069 }
2070 }
2071}
2072
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002073/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2074private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2075 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2076
2077 /* first perform regular attach */
2078 f_TC_attach(id);
2079 /* then activate PDP context */
2080 f_pdp_ctx_act(apars);
2081 /* then transceive a downlink PDU */
2082 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2083
2084 /* Send Error indication as response from upload PDU and expect deact towards MS */
2085 f_pdp_ctx_deact_mt(apars, true);
2086}
2087testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2088 var BSSGP_ConnHdlr vc_conn;
2089 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002090 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 +02002091 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002092 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002093}
2094
Alexander Couzens5e307b42018-05-22 18:12:20 +02002095testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2096 /* MS <-> SGSN: GMM Attach
2097 * HLR -> SGSN: Cancel Location Request
2098 * HLR <- SGSN: Cancel Location Ack
2099 */
2100 var BSSGP_ConnHdlr vc_conn;
2101 f_init();
2102 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002103 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002104 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002105 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002106}
2107
2108
Alexander Couzensc87967a2018-05-22 16:09:54 +02002109private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2110 /* MS: perform regular attach */
2111 f_TC_attach(id);
2112
2113 /* HLR: cancel the location request */
2114 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2115 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2116 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2117
2118 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002119 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002120 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002121
2122 setverdict(pass);
2123}
2124
2125testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2126 /* MS <-> SGSN: GMM Attach
2127 * HLR -> SGSN: Cancel Location Request
2128 * HLR <- SGSN: Cancel Location Ack
2129 * MS <- SGSN: Detach Request
2130 * SGSN-> MS: Detach Complete
2131 */
2132 var BSSGP_ConnHdlr vc_conn;
2133 f_init();
2134 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002135 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002136 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002137 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002138}
2139
2140
Alexander Couzens6c47f292018-05-22 17:09:49 +02002141private function f_hlr_location_cancel_request_unknown_subscriber(
2142 charstring id,
2143 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2144
2145 /* HLR: cancel the location request */
2146 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2147
2148 /* cause 2 = IMSI_UNKNOWN */
2149 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2150
2151 setverdict(pass);
2152}
2153
2154private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002155 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002156}
2157
2158testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2159 /* HLR -> SGSN: Cancel Location Request
2160 * HLR <- SGSN: Cancel Location Error
2161 */
2162
2163 var BSSGP_ConnHdlr vc_conn;
2164 f_init();
2165 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002166 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 +02002167 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002168 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002169}
2170
2171private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002172 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002173}
2174
2175testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2176 /* HLR -> SGSN: Cancel Location Request
2177 * HLR <- SGSN: Cancel Location Error
2178 */
2179
2180 var BSSGP_ConnHdlr vc_conn;
2181 f_init();
2182 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002183 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_unknown_subscriber_update), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002184 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002185 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002186}
2187
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002188private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2189 f_TC_attach(id);
2190 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2191}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002192
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002193testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2194 /* MS <-> SGSN: Attach
2195 * MS -> SGSN: Detach Req (Power off)
2196 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2197 */
2198 var BSSGP_ConnHdlr vc_conn;
2199 var integer id := 33;
2200 var charstring imsi := hex2str(f_gen_imsi(id));
2201
2202 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002203 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002204 vc_conn.done;
2205
2206 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002207 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002208}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002209
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002210/* Attempt an attach, but loose the Identification Request (IMEI) */
2211private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2212 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002213 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002214
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002215 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 +02002216
2217 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002218 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002219 /* break */
2220 }
Harald Welte955aa942019-05-03 01:29:29 +02002221 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002222 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002223 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002224 repeat;
2225 }
Harald Welte955aa942019-05-03 01:29:29 +02002226 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002227 /* ignore ID REQ IMEI */
2228 count_req := count_req + 1;
2229 repeat;
2230 }
2231 }
2232 if (count_req != 5) {
2233 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002234 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002235 }
2236 setverdict(pass);
2237}
2238
2239testcase TC_attach_no_imei_response() runs on test_CT {
2240 /* MS -> SGSN: Attach Request IMSI
2241 * MS <- SGSN: Identity Request IMSI (optional)
2242 * MS -> SGSN: Identity Response IMSI (optional)
2243 * MS <- SGSN: Identity Request IMEI
2244 * MS -x SGSN: no response
2245 * MS <- SGSN: re-send: Identity Request IMEI 4x
2246 * MS <- SGSN: Attach Reject
2247 */
2248 var BSSGP_ConnHdlr vc_conn;
2249 f_init();
2250 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002251 vc_conn := f_start_handler(refers(f_TC_attach_no_imei_response), testcasename(), g_gb, 32, 60.0);
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002252 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002253 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002254}
2255
Alexander Couzens53f20562018-06-12 16:24:12 +02002256/* Attempt an attach, but loose the Identification Request (IMSI) */
2257private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2258 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002259 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002260
2261 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2262 g_pars.p_tmsi := 'c0000035'O;
2263
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002264 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 +02002265
2266 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002267 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002268 /* break */
2269 }
Harald Welte955aa942019-05-03 01:29:29 +02002270 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002271 /* ignore ID REQ IMSI */
2272 count_req := count_req + 1;
2273 repeat;
2274 }
Harald Welte955aa942019-05-03 01:29:29 +02002275 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002276 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002277 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002278 repeat;
2279 }
2280 }
2281 if (count_req != 5) {
2282 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002283 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002284 }
2285 setverdict(pass);
2286}
2287
2288testcase TC_attach_no_imsi_response() runs on test_CT {
2289 /* MS -> SGSN: Attach Request TMSI (unknown)
2290 * MS <- SGSN: Identity Request IMEI (optional)
2291 * MS -> SGSN: Identity Response IMEI (optional)
2292 * MS <- SGSN: Identity Request IMSI
2293 * MS -x SGSN: no response
2294 * MS <- SGSN: re-send: Identity Request IMSI 4x
2295 * MS <- SGSN: Attach Reject
2296 */
2297 var BSSGP_ConnHdlr vc_conn;
2298 f_init();
2299 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002300 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 +02002301 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002302 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002303}
2304
Alexander Couzenscf818962018-06-05 18:00:00 +02002305private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2306 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2307}
2308
2309testcase TC_attach_check_subscriber_list() runs on test_CT {
2310 /* MS <-> SGSN: Attach
2311 * VTY -> SGSN: Check if MS is in subscriber cache
2312 */
2313 var BSSGP_ConnHdlr vc_conn;
2314 var integer id := 34;
2315 var charstring imsi := hex2str(f_gen_imsi(id));
2316
2317 f_init();
2318 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002319 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002320 vc_conn.done;
2321
2322 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2323 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002324 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002325}
2326
Alexander Couzensf9858652018-06-07 16:14:53 +02002327private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2328 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002329 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002330
2331 /* unregister the old IMSI */
2332 f_bssgp_client_unregister(g_pars.imsi);
2333 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002334 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002335 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002336
2337 /* there is no auth */
2338 g_pars.net.expect_auth := false;
2339
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002340 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002341 f_gmm_auth();
2342 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002343 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002344 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002345 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002346 }
Harald Welte955aa942019-05-03 01:29:29 +02002347 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2348 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002349 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002350 setverdict(pass);
2351 }
2352 }
2353}
Alexander Couzens03d12242018-08-07 16:13:52 +02002354
2355private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2356
2357 f_TC_attach_closed_foreign(id);
2358 f_TC_attach_closed_imsi_added(id);
2359
2360}
2361
2362
Alexander Couzensf9858652018-06-07 16:14:53 +02002363testcase TC_attach_closed_add_vty() runs on test_CT {
2364 /* VTY-> SGSN: policy close
2365 * MS -> SGSN: Attach Request
2366 * MS <- SGSN: Identity Request IMSI
2367 * MS -> SGSN: Identity Response IMSI
2368 * MS <- SGSN: Attach Reject
2369 * VTY-> SGSN: policy imsi-acl add IMSI
2370 * MS -> SGSN: Attach Request
2371 * MS <- SGSN: Identity Request IMSI
2372 * MS -> SGSN: Identity Response IMSI
2373 * MS <- SGSN: Identity Request IMEI
2374 * MS -> SGSN: Identity Response IMEI
2375 * MS <- SGSN: Attach Accept
2376 */
2377 var BSSGP_ConnHdlr vc_conn;
2378 f_init();
2379 f_sleep(1.0);
2380 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2381 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002382 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2383 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002384 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002385 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002386 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002387 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002388}
2389
Alexander Couzens0085bd72018-06-12 19:08:44 +02002390/* Attempt an attach, but never answer a Attach Complete */
2391private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2392 var integer count_req := 0;
2393
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002394 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 +02002395 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002396 /* Expect SGSN to perform LU with HLR */
2397 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002398
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002399 timer T := 10.0;
2400 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002401 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002402 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002403 /* break */
2404 }
Harald Welte955aa942019-05-03 01:29:29 +02002405 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002406 /* ignore */
2407 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002408 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002409 repeat;
2410 }
2411 }
2412 if (count_req != 5) {
2413 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002414 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002415 }
2416 setverdict(pass);
2417}
2418
2419testcase TC_attach_check_complete_resend() runs on test_CT {
2420 /* MS -> SGSN: Attach Request IMSI
2421 * MS <- SGSN: Identity Request *
2422 * MS -> SGSN: Identity Response *
2423 * MS <- SGSN: Attach Complete 5x
2424 */
2425 var BSSGP_ConnHdlr vc_conn;
2426 f_init();
2427 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002428 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 +02002429 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002430 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002431}
2432
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002433friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002434 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002435 var PDU_DTAP_PS_MT mt;
2436 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002437
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002438 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002439 p_tmsi := g_pars.p_tmsi;
2440 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002441 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002442 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 +02002443 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002444 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2445 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2446 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002447 setverdict(pass);
2448 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002449 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2450 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2451 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002452 setverdict(pass);
2453 }
2454
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002455 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002456 setverdict(fail, "Unexpected RAU Reject");
2457 mtc.stop;
2458 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002459 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002460 setverdict(fail, "Unexpected RAU Reject");
2461 mtc.stop;
2462 }
2463
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002464 [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 +02002465 key_sts := ?)) {
2466 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2467 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002468 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002469 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002470 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002471 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2472 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002473 }
2474}
2475
Alexander Couzensbfda9212018-07-31 03:17:33 +02002476private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002477 /* first perform regular attach */
2478 f_TC_attach(id);
2479
2480 /* then send RAU */
2481 f_routing_area_update(g_pars.ra);
2482
2483 /* do another RAU */
2484 f_routing_area_update(g_pars.ra);
2485
2486 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2487}
2488
2489testcase TC_attach_rau_a_a() runs on test_CT {
2490 /* MS <-> SGSN: Successful Attach
2491 * MS -> SGSN: Routing Area Update Request
2492 * MS <- SGSN: Routing Area Update Accept
2493 * MS -> SGSN: Routing Area Update Request
2494 * MS <- SGSN: Routing Area Update Accept
2495 * MS -> SGSN: Detach (PowerOff)
2496 */
2497 var BSSGP_ConnHdlr vc_conn;
2498 f_init();
2499 f_sleep(1.0);
2500 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2501 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002502 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002503}
2504
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002505private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002506 f_TC_attach(id);
2507
2508 log("attach complete sending rau");
2509 f_routing_area_update(g_pars.ra, 0);
2510
2511 log("rau complete unregistering");
2512 f_bssgp_client_unregister(g_pars.imsi);
2513 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2514
2515 log("sending second RAU via different RA");
2516 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2517
2518 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2519}
2520
2521testcase TC_attach_rau_a_b() runs on test_CT {
2522 /* MS <-> SGSN: Successful Attach
2523 * MS -> SGSN: Routing Area _a_ Update Request
2524 * MS <- SGSN: Routing Area _a_ Update Accept
2525 * MS -> SGSN: Routing Area _b_ Update Request
2526 * MS <- SGSN: Routing Area _b_ Update Accept
2527 * MS -> SGSN: Detach (PowerOff)
2528 */
2529 var BSSGP_ConnHdlr vc_conn;
2530 f_init();
2531 f_sleep(1.0);
2532 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2533 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002534 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002535}
2536
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002537private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2538 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002539 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002540 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002541 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002542
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002543 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002544
2545 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002546 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002547 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2548 mtc.stop;
2549 }
Harald Welte955aa942019-05-03 01:29:29 +02002550 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002551 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002552 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002553 repeat;
2554 }
Harald Welte955aa942019-05-03 01:29:29 +02002555 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002556 /* send out a second GMM_Attach Request.
2557 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2558 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002559 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002560 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002561 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002562 }
2563 }
2564 f_sleep(1.0);
2565
2566 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2567 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002568 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002569 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002570 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002571 repeat;
2572 }
Harald Welte955aa942019-05-03 01:29:29 +02002573 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002574 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2575 mtc.stop;
2576 }
Harald Welte955aa942019-05-03 01:29:29 +02002577 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002578 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2579 mtc.stop;
2580 }
Harald Welte955aa942019-05-03 01:29:29 +02002581 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2582 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002583 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002584 setverdict(pass);
2585 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2586 }
2587 }
2588}
2589
2590testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2591 /* Testing if the SGSN ignore Attach Request with the exact same content */
2592 /* MS -> SGSN: Attach Request IMSI
2593 * MS <- SGSN: Identity Request IMSI (optional)
2594 * MS -> SGSN: Identity Response IMSI (optional)
2595 * MS <- SGSN: Identity Request IMEI
2596 * MS -> SGSN: Attach Request (2nd)
2597 * MS <- SGSN: Identity Response IMEI
2598 * MS <- SGSN: Attach Accept
2599 * MS -> SGSN: Attach Complete
2600 */
2601 var BSSGP_ConnHdlr vc_conn;
2602 f_init();
2603 f_sleep(1.0);
2604 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2605 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2606 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002607 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002608}
2609
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002610private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002611 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2612
2613 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2614
2615 /* send Attach Request */
2616 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2617 * 3G auth vectors */
2618 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2619 /* The thing is, if the solSACapability is 'omit', then the
2620 * revisionLevelIndicatior is at the wrong place! */
2621 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002622 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002623
2624 /* do the auth */
2625 var PDU_L3_MS_SGSN l3_mo;
2626 var PDU_L3_SGSN_MS l3_mt;
2627 var default di := activate(as_mm_identity());
2628
2629 var GSUP_IE auth_tuple;
2630 var template AuthenticationParameterAUTNTLV autn;
2631
2632 g_pars.vec := f_gen_auth_vec_3g();
2633 autn := {
2634 elementIdentifier := '28'O,
2635 lengthIndicator := lengthof(g_pars.vec.autn),
2636 autnValue := g_pars.vec.autn
2637 };
2638 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2639 g_pars.vec.sres,
2640 g_pars.vec.kc,
2641 g_pars.vec.ik,
2642 g_pars.vec.ck,
2643 g_pars.vec.autn,
2644 g_pars.vec.res));
2645 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2646 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2647 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2648
2649 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2650 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002651 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002652
2653 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002654 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002655
2656 /* wait for the GSUP resync request */
2657 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2658 g_pars.imsi,
2659 g_pars.vec.auts,
2660 g_pars.vec.rand));
2661
2662 /* generate new key material */
2663 g_pars.vec := f_gen_auth_vec_3g();
2664 autn := {
2665 elementIdentifier := '28'O,
2666 lengthIndicator := lengthof(g_pars.vec.autn),
2667 autnValue := g_pars.vec.autn
2668 };
2669
2670 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2671 g_pars.vec.sres,
2672 g_pars.vec.kc,
2673 g_pars.vec.ik,
2674 g_pars.vec.ck,
2675 g_pars.vec.autn,
2676 g_pars.vec.res));
2677 /* send new key material */
2678 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2679
2680 /* wait for the new Auth Request */
2681 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2682 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002683 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002684 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2685 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2686 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2687 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2688 valueField := substr(g_pars.vec.res, 0, 4)
2689 };
2690 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2691 elementIdentifier := '21'O,
2692 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2693 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2694 };
2695 l3_mo := valueof(auth_ciph_resp);
2696 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2697 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2698 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2699 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2700 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002701 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002702 deactivate(di);
2703
2704 /* Expect SGSN to perform LU with HLR */
2705 f_gmm_gsup_lu_isd();
2706
Harald Welte955aa942019-05-03 01:29:29 +02002707 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2708 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002709 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002710 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002711 setverdict(pass);
2712}
2713
2714testcase TC_attach_usim_resync() runs on test_CT {
2715 /* MS -> SGSN: Attach Request
2716 * MS <- SGSN: Identity Request IMSI
2717 * MS -> SGSN: Identity Response IMSI
2718 * MS <- SGSN: Identity Request IMEI
2719 * MS -> SGSN: Identity Response IMEI
2720 * HLR<- SGSN: SAI Request
2721 * HLR-> SGSN: SAI Response
2722 * MS <- SGSN: Auth Request
2723 * MS -> SGSN: Auth Failure (with AUTS)
2724 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2725 * HLR-> SGSN: SAI Response (new key material)
2726 * MS <- SGSN: Auth Request (new key material)
2727 * MS -> SGSN: Auth Response
2728 * MS <- SGSN: Attach Accept
2729 * MS -> SGSN: Attach Complete
2730 */
2731 var BSSGP_ConnHdlr vc_conn;
2732 f_init();
2733 f_sleep(1.0);
2734 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2735 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002736 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002737}
2738
Harald Weltea05b8072019-04-23 22:35:05 +02002739
2740/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2741private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2742 f_gmm_attach(false, false);
2743 f_sleep(1.0);
2744 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2745 /* try to detach to check if SGSN is still alive */
2746 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2747}
2748testcase TC_llc_null() runs on test_CT {
2749 var BSSGP_ConnHdlr vc_conn;
2750 f_init();
2751 f_sleep(1.0);
2752 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2753 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002754 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002755}
2756
Harald Welte645a1512019-04-23 23:18:23 +02002757/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2758private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2759 f_gmm_attach(false, false);
2760 f_sleep(1.0);
2761 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002762 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002763 setverdict(pass);
2764}
2765testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2766 var BSSGP_ConnHdlr vc_conn;
2767 f_init();
2768 f_sleep(1.0);
2769 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2770 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002771 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002772}
2773
2774/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2775private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2776 f_gmm_attach(false, false);
2777 f_sleep(1.0);
2778 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002779 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002780 setverdict(pass);
2781}
2782testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2783 var BSSGP_ConnHdlr vc_conn;
2784 f_init();
2785 f_sleep(1.0);
2786 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2787 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002788 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002789}
2790
Harald Welte2aaac1b2019-05-02 10:02:53 +02002791/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2792private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2793 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2794 var template (value) XID_Information xid;
2795 var template XID_Information xid_rx;
2796
2797 /* first perform regular attach */
2798 f_TC_attach(id);
2799 /* then activate PDP context */
2800 f_pdp_ctx_act(apars);
2801
2802 /* start MO XID */
2803 xid := { ts_XID_L3(''O) };
2804 xid_rx := { tr_XID_L3(''O) };
2805 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2806 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002807 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002808 [] as_xid(apars);
2809 }
2810 setverdict(pass);
2811}
2812testcase TC_xid_empty_l3() runs on test_CT {
2813 var BSSGP_ConnHdlr vc_conn;
2814 f_init();
2815 f_sleep(1.0);
2816 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2817 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002818 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002819}
2820
2821private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2822 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2823 var template (value) XID_Information xid;
2824 var template XID_Information xid_rx;
2825
2826 /* first perform regular attach */
2827 f_TC_attach(id);
2828 /* then activate PDP context */
2829 f_pdp_ctx_act(apars);
2830
2831 /* start MO XID */
2832 xid := { ts_XID_N201U(1234) };
2833 xid_rx := { tr_XID_N201U(1234) };
2834 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2835 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002836 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002837 [] as_xid(apars);
2838 }
2839 setverdict(pass);
2840}
2841testcase TC_xid_n201u() runs on test_CT {
2842 var BSSGP_ConnHdlr vc_conn;
2843 f_init();
2844 f_sleep(1.0);
2845 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2846 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002847 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002848}
2849
Alexander Couzens6bee0872019-05-11 01:48:50 +02002850private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2851 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2852
2853 /* first perform regular attach */
2854 f_TC_attach(id);
2855 /* then activate PDP context */
2856 f_pdp_ctx_act(apars);
2857 /* do a normal detach */
2858 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2859}
2860
2861testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2862 /* MS -> SGSN: Attach Request
2863 * MS <-> SGSN: [..]
2864 * MS -> SGSN: Attach Complete
2865 * MS -> SGSN: PDP Activate Request
2866 * MS <- SGSN: PDP Activate Accept
2867 * MS -> SGSN: GMM Detach Request
2868 * MS <- SGSN: GMM Detach Accept
2869 */
2870 var BSSGP_ConnHdlr vc_conn;
2871 f_init();
2872 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2873 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002874 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002875}
Harald Welte645a1512019-04-23 23:18:23 +02002876
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002877private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2878 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2879 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2880 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2881 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2882 var PDU_L3_SGSN_MS l3_mt;
2883
2884 f_send_l3(attach_req, 0);
2885
2886 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2887
2888 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2889 alt {
2890 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2891 setverdict(pass);
2892 }
2893 [] BSSGP[0].receive { repeat; }
2894 }
2895}
2896
2897/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2898 * See OS#3957 and OS#4245 for more information.
2899 */
2900testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2901 /*
2902 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2903 * MS <-- SGSN: Identity Request (IMEI)
2904 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2905 */
2906 var BSSGP_ConnHdlr vc_conn;
2907 f_init();
2908 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2909 vc_conn.done;
2910 f_cleanup();
2911}
2912
Harald Welte8e5932e2020-06-17 22:12:54 +02002913private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2914var PDU_BSSGP rx;
2915[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2916 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2917 mtc.stop;
2918 }
2919}
2920
2921/* SUSPEND, then DL traffic: should not pass + no paging expected */
2922private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2923 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2924 var default d;
2925
2926 /* first perform regular attach */
2927 f_TC_attach(id);
2928 /* then activate PDP context */
2929 f_pdp_ctx_act(apars);
2930 /* then transceive a downlink PDU */
2931 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2932
2933 /* now suspend GPRS */
2934 f_bssgp_suspend();
2935
2936 d := activate(as_nopaging_ps());
2937
2938 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2939 * nor any related paging requests */
2940 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2941
2942 deactivate(d);
2943}
2944testcase TC_suspend_nopaging() runs on test_CT {
2945 var BSSGP_ConnHdlr vc_conn;
2946 f_init();
2947 f_sleep(1.0);
2948 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
2949 vc_conn.done;
2950 f_cleanup();
2951}
2952
2953
2954/* SUSPEND, then RESUME: data expected to flow after explicit resume */
2955private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
2956 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2957 var OCT1 susp_ref;
2958 var default d;
2959
2960 /* first perform regular attach */
2961 f_TC_attach(id);
2962 /* then activate PDP context */
2963 f_pdp_ctx_act(apars);
2964 /* then transceive a downlink PDU */
2965 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2966
2967 /* now suspend GPRS */
2968 susp_ref := f_bssgp_suspend();
2969
2970 d := activate(as_nopaging_ps());
2971
2972 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2973 * nor any related paging requests */
2974 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2975
2976 deactivate(d);
2977
2978 /* resume GPRS */
2979 f_bssgp_resume(susp_ref);
2980
2981 /* now data should be flowing again */
2982 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2983}
2984testcase TC_suspend_resume() runs on test_CT {
2985 var BSSGP_ConnHdlr vc_conn;
2986 f_init();
2987 f_sleep(1.0);
2988 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
2989 vc_conn.done;
2990 f_cleanup();
2991}
2992
2993/* SUSPEND, then RAU: data expected to flow after implicit resume */
2994private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
2995 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2996 var default d;
2997
2998 /* first perform regular attach */
2999 f_TC_attach(id);
3000 /* then activate PDP context */
3001 f_pdp_ctx_act(apars);
3002 /* then transceive a downlink PDU */
3003 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3004
3005 /* now suspend GPRS */
3006 f_bssgp_suspend();
3007
3008 d := activate(as_nopaging_ps());
3009
3010 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3011 * nor any related paging requests */
3012 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3013
3014 deactivate(d);
3015
3016 /* perform RAU (implicit RESUME) */
3017 f_routing_area_update(g_pars.ra);
3018
3019 /* now data should be flowing again */
3020 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3021
3022}
3023testcase TC_suspend_rau() runs on test_CT {
3024 var BSSGP_ConnHdlr vc_conn;
3025 f_init();
3026 f_sleep(1.0);
3027 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3028 vc_conn.done;
3029 f_cleanup();
3030}
3031
3032
3033/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3034private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3035 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3036 var default d;
3037
3038 /* first perform regular attach */
3039 f_TC_attach(id);
3040 /* then activate PDP context */
3041 f_pdp_ctx_act(apars);
3042 /* then transceive a downlink PDU */
3043 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3044
3045 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3046 f_sleep(5.0);
3047
3048 /* now data should be flowing again, but with PS PAGING */
3049 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3050 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3051
3052 /* FIXME: simulate paging response */
3053 /* FIXME: verify PDU actually arrives only after paging response was successful */
3054
3055}
3056testcase TC_paging_ps() runs on test_CT {
3057 var BSSGP_ConnHdlr vc_conn;
3058 f_init();
3059 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3060 f_sleep(1.0);
3061 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3062 vc_conn.done;
3063 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3064 f_cleanup();
3065}
3066
3067
3068
3069
3070
Harald Welte5ac31492018-02-15 20:39:13 +01003071control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003072 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003073 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003074 execute( TC_attach_umts_aka_umts_res() );
3075 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003076 execute( TC_attach_auth_id_timeout() );
3077 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003078 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003079 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003080 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003081 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003082 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003083 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003084 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003085 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003086 execute( TC_attach_closed_add_vty(), 20.0 );
3087 execute( TC_attach_check_subscriber_list(), 20.0 );
3088 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003089 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003090 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3091 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3092 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3093 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003094 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003095 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003096 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003097 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003098 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003099 execute( TC_detach_unknown_nopoweroff() );
3100 execute( TC_detach_unknown_poweroff() );
3101 execute( TC_detach_nopoweroff() );
3102 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003103 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003104 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003105 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003106 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003107 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003108 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003109 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003110 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003111 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003112 execute( TC_attach_restart_ctr_echo() );
3113 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003114 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003115 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3116 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003117 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003118 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003119 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003120
Harald Welte2aaac1b2019-05-02 10:02:53 +02003121 execute( TC_xid_empty_l3() );
3122 execute( TC_xid_n201u() );
3123
Harald Weltea05b8072019-04-23 22:35:05 +02003124 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003125 execute( TC_llc_sabm_dm_llgmm() );
3126 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003127
Harald Welte8e5932e2020-06-17 22:12:54 +02003128 execute( TC_suspend_nopaging() );
3129 execute( TC_suspend_resume() );
3130 execute( TC_suspend_rau() );
3131 execute( TC_paging_ps() );
3132
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003133 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3134 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003135}
Harald Welte96a33b02018-02-04 10:36:22 +01003136
3137
3138
3139}