blob: 870e66fefa39918fbd5cd80b09e67f225a9f442d [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020018import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010019import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010020import from NS_Types all;
21import from NS_Emulation all;
22import from BSSGP_Types all;
23import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010024import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020025import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010026
27import from MobileL3_CommonIE_Types all;
28import from MobileL3_GMM_SM_Types all;
29import from MobileL3_Types all;
30import from L3_Templates all;
31import from L3_Common all;
32
33import from GSUP_Emulation all;
34import from GSUP_Types all;
35import from IPA_Emulation all;
36
Harald Welte26fbb6e2019-04-14 17:32:46 +020037import from RAN_Adapter all;
38import from RAN_Emulation all;
39import from RANAP_Templates all;
40import from RANAP_PDU_Descriptions all;
41import from RANAP_IEs all;
42
Harald Welteeded9ad2018-02-17 20:57:34 +010043import from GTP_Emulation all;
44import from GTP_Templates all;
45import from GTP_CodecPort all;
46import from GTPC_Types all;
47import from GTPU_Types all;
48
Harald Weltea2526a82018-02-18 19:03:36 +010049import from LLC_Types all;
50import from LLC_Templates all;
51
52import from SNDCP_Types all;
53
Harald Weltebd194722018-02-16 22:11:08 +010054import from TELNETasp_PortType all;
55import from Osmocom_VTY_Functions all;
56
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010057import from GSM_RR_Types all;
58
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020059import from MobileL3_MM_Types all;
60
Harald Welteeded9ad2018-02-17 20:57:34 +010061
Harald Welte5ac31492018-02-15 20:39:13 +010062modulepar {
63 /* IP/port on which we run our internal GSUP/HLR emulation */
64 charstring mp_hlr_ip := "127.0.0.1";
65 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010066 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020067 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020068
Alexander Couzensf3c1b412018-08-24 00:42:51 +020069 NSConfigurations mp_nsconfig := {
70 {
71 local_udp_port := 21010,
72 local_ip := "127.0.0.1",
73 remote_udp_port := 23000,
74 remote_ip := "127.0.0.1",
75 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020076 nsei := 96,
77 role_sgsn := false,
78 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020079 },
80 {
81 local_udp_port := 21011,
82 local_ip := "127.0.0.1",
83 remote_udp_port := 23000,
84 remote_ip := "127.0.0.1",
85 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020086 nsei := 97,
87 role_sgsn := false,
88 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020089 },
90 {
91 local_udp_port := 21012,
92 local_ip := "127.0.0.1",
93 remote_udp_port := 23000,
94 remote_ip := "127.0.0.1",
95 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020096 nsei := 98,
97 role_sgsn := false,
98 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020099 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200100 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200101
102 RAN_Configurations mp_ranap_cfg := {
103 {
104 transport := RANAP_TRANSPORT_IuCS,
105 sccp_service_type := "mtp3_itu",
106 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
107 own_pc := 195,
108 own_ssn := 142,
109 peer_pc := 188, /* 0.23.4 */
110 peer_ssn := 142,
111 sio := '83'O,
112 rctx := 2
113 }
114 }
Harald Welte5ac31492018-02-15 20:39:13 +0100115};
116
117type record GbInstance {
118 NS_CT vc_NS,
119 BSSGP_CT vc_BSSGP,
120 BssgpConfig cfg
121};
Harald Welte96a33b02018-02-04 10:36:22 +0100122
Harald Welte2fa771f2019-05-02 20:13:53 +0200123const integer NUM_GB := 3;
124type record length(NUM_GB) of GbInstance GbInstances;
125type record length(NUM_GB) of NSConfiguration NSConfigurations;
126type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200127
Harald Welte26fbb6e2019-04-14 17:32:46 +0200128const integer NUM_RNC := 1;
129type record of RAN_Configuration RAN_Configurations;
130
Harald Welte96a33b02018-02-04 10:36:22 +0100131type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200132 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200133 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200134 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100135
Harald Welte5ac31492018-02-15 20:39:13 +0100136 var GSUP_Emulation_CT vc_GSUP;
137 var IPA_Emulation_CT vc_GSUP_IPA;
138 /* only to get events from IPA underneath GSUP */
139 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100140
Harald Welteeded9ad2018-02-17 20:57:34 +0100141 var GTP_Emulation_CT vc_GTP;
142
Harald Weltebd194722018-02-16 22:11:08 +0100143 port TELNETasp_PT SGSNVTY;
144
Harald Welte96a33b02018-02-04 10:36:22 +0100145 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200146 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100147};
148
Harald Welte26fbb6e2019-04-14 17:32:46 +0200149type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100150 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100151 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200152 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100153}
154
155type record SGSN_ConnHdlrNetworkPars {
156 boolean expect_ptmsi,
157 boolean expect_auth,
158 boolean expect_ciph
159};
160
161type record BSSGP_ConnHdlrPars {
162 /* IMEI of the simulated ME */
163 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200164 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100165 hexstring imsi,
166 /* MSISDN of the simulated MS (probably unused) */
167 hexstring msisdn,
168 /* P-TMSI allocated to the simulated MS */
169 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100170 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100171 /* TLLI of the simulated MS */
172 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100173 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100174 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200175 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200176 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
177 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100178 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100179 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200180 float t_guard,
181 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200182 SCCP_PAR_Address sccp_addr_local optional,
183 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100184};
185
Alexander Couzens89508702018-07-31 04:16:10 +0200186private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200187 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200188 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
189
190 var RoutingAreaIdentificationV ret := {
191 mccDigit1 := mcc_mnc[0],
192 mccDigit2 := mcc_mnc[1],
193 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200194 mncDigit3 := mcc_mnc[3],
195 mncDigit1 := mcc_mnc[4],
196 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200197 lac := int2oct(cell_id.ra_id.lai.lac, 16),
198 rac := int2oct(cell_id.ra_id.rac, 8)
199 }
200 return ret;
201};
202
Alexander Couzens51114d12018-07-31 18:41:56 +0200203private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
204 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
205 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100206 /* connect lower end of BSSGP emulation with NS upper port */
207 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100208
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200209 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100210 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
211}
212
213private function f_init_gsup(charstring id) runs on test_CT {
214 id := id & "-GSUP";
215 var GsupOps ops := {
216 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
217 };
218
219 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
220 vc_GSUP := GSUP_Emulation_CT.create(id);
221
222 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
223 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
224 /* we use this hack to get events like ASP_IPA_EVENT_UP */
225 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
226
227 vc_GSUP.start(GSUP_Emulation.main(ops, id));
228 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
229
230 /* wait for incoming connection to GSUP port before proceeding */
231 timer T := 10.0;
232 T.start;
233 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700234 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100235 [] T.timeout {
236 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200237 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100238 }
239 }
240}
241
Harald Welteeded9ad2018-02-17 20:57:34 +0100242private function f_init_gtp(charstring id) runs on test_CT {
243 id := id & "-GTP";
244
245 var GtpEmulationCfg gtp_cfg := {
246 gtpc_bind_ip := mp_ggsn_ip,
247 gtpc_bind_port := GTP1C_PORT,
248 gtpu_bind_ip := mp_ggsn_ip,
249 gtpu_bind_port := GTP1U_PORT,
250 sgsn_role := false
251 };
252
253 vc_GTP := GTP_Emulation_CT.create(id);
254 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
255}
256
Harald Weltebd194722018-02-16 22:11:08 +0100257private function f_init_vty() runs on test_CT {
258 map(self:SGSNVTY, system:SGSNVTY);
259 f_vty_set_prompts(SGSNVTY);
260 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200261 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100262 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
263}
264
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200265private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
266 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200267 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200268 } else {
269 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
270 }
271}
272
Harald Weltebd194722018-02-16 22:11:08 +0100273
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200274/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
275function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200276 var integer i;
277
Harald Welte96a33b02018-02-04 10:36:22 +0100278 if (g_initialized == true) {
279 return;
280 }
281 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100282 g_gb[0].cfg := {
283 nsei := 96,
284 bvci := 196,
285 cell_id := {
286 ra_id := {
287 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100288 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100289 rac := 0
290 },
291 cell_id := 20960
292 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200293 sgsn_role := false,
294 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100295 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200296 g_gb[1].cfg := {
297 nsei := 97,
298 bvci := 210,
299 cell_id := {
300 ra_id := {
301 lai := {
302 mcc_mnc := mcc_mnc, lac := 13200},
303 rac := 0
304 },
305 cell_id := 20961
306 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200307 sgsn_role := false,
308 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200309 };
310 g_gb[2].cfg := {
311 nsei := 98,
312 bvci := 220,
313 cell_id := {
314 ra_id := {
315 lai := {
316 mcc_mnc := mcc_mnc, lac := 13300},
317 rac := 0
318 },
319 cell_id := 20962
320 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200321 sgsn_role := false,
322 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200323 };
Harald Welte96a33b02018-02-04 10:36:22 +0100324
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200325 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200326 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
327 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
328 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200329
Alexander Couzens1552e792019-07-23 20:38:39 +0200330 if (g_ranap_enable) {
331 for (i := 0; i < NUM_RNC; i := i+1) {
332 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
333 f_ran_adapter_start(g_ranap[i]);
334 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200335 }
Harald Welte5ac31492018-02-15 20:39:13 +0100336 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100337 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200338 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100339}
Harald Welte96a33b02018-02-04 10:36:22 +0100340
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200341function f_cleanup() runs on test_CT {
342 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200343 if (g_ranap_enable) {
344 for (i := 0; i < NUM_RNC; i := i+1) {
345 f_ran_adapter_cleanup(g_ranap[i]);
346 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200347 }
348 self.stop;
349}
350
Harald Welte26fbb6e2019-04-14 17:32:46 +0200351private function RncUnitdataCallback(RANAP_PDU ranap)
352runs on RAN_Emulation_CT return template RANAP_PDU {
353 var template RANAP_PDU resp := omit;
354
355 log ("RANAP_RncUnitDataCallback");
356 /* answer all RESET with RESET ACK */
357 if (match(ranap, tr_RANAP_Reset)) {
358 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
359 var CN_DomainIndicator dom;
360 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
361 resp := ts_RANAP_ResetAck(dom);
362 }
363 return resp;
364}
365
366const RanOps RNC_RanOps := {
367 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
368 ranap_unitdata_cb := refers(RncUnitdataCallback),
369 ps_domain := true,
370 decode_dtap := true,
371 role_ms := true,
372 protocol := RAN_PROTOCOL_RANAP,
373 transport := RANAP_TRANSPORT_IuCS,
374 use_osmux := false,
375 sccp_addr_local := omit,
376 sccp_addr_peer := omit
377};
378
Harald Welte5ac31492018-02-15 20:39:13 +0100379type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
380
381/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200382function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100383 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100384runs on test_CT return BSSGP_ConnHdlr {
385 var BSSGP_ConnHdlr vc_conn;
386 var SGSN_ConnHdlrNetworkPars net_pars := {
387 expect_ptmsi := true,
388 expect_auth := true,
389 expect_ciph := false
390 };
391 var BSSGP_ConnHdlrPars pars := {
392 imei := f_gen_imei(imsi_suffix),
393 imsi := f_gen_imsi(imsi_suffix),
394 msisdn := f_gen_msisdn(imsi_suffix),
395 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100396 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100397 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100398 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100399 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200400 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 +0200401 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100402 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100403 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200404 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200405 sccp_addr_local := omit,
406 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100407 };
408
Alexander Couzens1552e792019-07-23 20:38:39 +0200409 if (g_ranap_enable) {
410 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
411 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
412 }
413
Harald Welte5ac31492018-02-15 20:39:13 +0100414 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200415 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200416 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200417 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
418 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200419 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200420 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
421 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200422 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200423 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100424
Harald Welte26fbb6e2019-04-14 17:32:46 +0200425 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200426 if (g_ranap_enable) {
427 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
428 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
429 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200430
Harald Welte5ac31492018-02-15 20:39:13 +0100431 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
432 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
433
Harald Welteeded9ad2018-02-17 20:57:34 +0100434 connect(vc_conn:GTP, vc_GTP:CLIENT);
435 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
436
Harald Welte5ac31492018-02-15 20:39:13 +0100437 vc_conn.start(f_handler_init(fn, id, pars));
438 return vc_conn;
439}
440
Harald Welte62e29582018-02-16 21:17:11 +0100441private altstep as_Tguard() runs on BSSGP_ConnHdlr {
442 [] g_Tguard.timeout {
443 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200444 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100445 }
446}
447
Harald Welte5ac31492018-02-15 20:39:13 +0100448/* first function called in every ConnHdlr */
449private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
450runs on BSSGP_ConnHdlr {
451 /* do some common stuff like setting up g_pars */
452 g_pars := pars;
453
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200454 llc := f_llc_create(false);
455
Harald Welte5ac31492018-02-15 20:39:13 +0100456 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200457 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100458 /* tell GSUP dispatcher to send this IMSI to us */
459 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100460 /* tell GTP dispatcher to send this IMSI to us */
461 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100462
Harald Welte62e29582018-02-16 21:17:11 +0100463 g_Tguard.start(pars.t_guard);
464 activate(as_Tguard());
465
Harald Welte5ac31492018-02-15 20:39:13 +0100466 /* call the user-supplied test case function */
467 fn.apply(id);
468 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100469}
470
471/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100472 * Detach without Attach
473 * SM procedures without attach / RAU
474 * ATTACH / RAU
475 ** with / without authentication
476 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100477 * re-transmissions of LLC frames
478 * PDP Context activation
479 ** with different GGSN config in SGSN VTY
480 ** with different PDP context type (v4/v6/v46)
481 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100482 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100483 */
484
485testcase TC_wait_ns_up() runs on test_CT {
486 f_init();
487 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200488 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100489}
490
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200491friend function is_gb(integer ran_index) return boolean {
492 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200493}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200494friend function is_iu(integer ran_index) return boolean {
495 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200496}
497
Alexander Couzens0507ec32019-09-15 22:41:22 +0200498function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200499 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200500 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 +0200501}
502
Alexander Couzens0507ec32019-09-15 22:41:22 +0200503private 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 +0200504 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
505 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
506 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200507 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200508}
509
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200510/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
511function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
512 log("Sending InitialUE: ", l3_mo);
513 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
514 var RANAP_PDU ranap;
515 var LAI lai := {
516 pLMNidentity := '62F224'O,
517 lAC := '1234'O,
518 iE_Extensions := omit
519 };
520 var SAI sai := {
521 pLMNidentity := lai.pLMNidentity,
522 lAC := lai.lAC,
523 sAC := '0000'O, /* FIXME */
524 iE_Extensions := omit
525 };
526 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
527 var GlobalRNC_ID grnc_id := {
528 pLMNidentity := lai.pLMNidentity,
529 rNC_ID := 2342 /* FIXME */
530 };
531
532 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
533 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
534 alt {
535 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
536 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
537 setverdict(fail, "DISC.ind from SCCP");
538 mtc.stop;
539 }
540 }
541}
542
543/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200544function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
545 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200546 if (g_pars.rnc_send_initial_ue) {
547 g_pars.rnc_send_initial_ue := false;
548 f_send_l3_initial_ue(l3_mo);
549 } else {
550 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
551 }
552 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200553 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200554 }
555}
556
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200557altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700558 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200559 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100560 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200561 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100562 repeat;
563 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200564 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200565 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200566 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200567 repeat;
568 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200569 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100570 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200571 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200572 repeat;
573 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200574 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200575 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200576 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100577 repeat;
578 }
579}
Harald Welte96a33b02018-02-04 10:36:22 +0100580
Harald Welteca362462019-05-02 20:11:21 +0200581/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200582function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200583runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200584 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200585 var PDU_L3_SGSN_MS l3_mt;
586 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200587 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
588 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200589 l3_mt := mt.dtap;
590 }
Harald Welteca362462019-05-02 20:11:21 +0200591 }
592 return l3_mt;
593}
594
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200595/* perform GMM authentication (if expected).
596 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
597 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200598function 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 +0100599 var PDU_L3_MS_SGSN l3_mo;
600 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200601 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100602 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200603 var GSUP_IE auth_tuple;
604 var template AuthenticationParameterAUTNTLV autn;
605
606 if (umts_aka_challenge) {
607 g_pars.vec := f_gen_auth_vec_3g();
608 autn := {
609 elementIdentifier := '28'O,
610 lengthIndicator := lengthof(g_pars.vec.autn),
611 autnValue := g_pars.vec.autn
612 };
613
614 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
615 g_pars.vec.sres,
616 g_pars.vec.kc,
617 g_pars.vec.ik,
618 g_pars.vec.ck,
619 g_pars.vec.autn,
620 g_pars.vec.res));
621 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
622 } else {
623 g_pars.vec := f_gen_auth_vec_2g();
624 autn := omit;
625 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
626 g_pars.vec.sres,
627 g_pars.vec.kc));
628 log("GSUP sends only 2G auth tuple", auth_tuple);
629 }
Harald Welteca362462019-05-02 20:11:21 +0200630
Harald Welte5ac31492018-02-15 20:39:13 +0100631 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
632 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200633
634 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
635 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200636 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100637 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200638 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
639
640 if (umts_aka_challenge and not force_gsm_sres) {
641 /* set UMTS response instead */
642 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
643 valueField := substr(g_pars.vec.res, 0, 4)
644 };
645 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
646 elementIdentifier := '21'O,
647 lengthIndicator := lengthof(g_pars.vec.res) - 4,
648 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
649 };
650 }
651
652 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100653 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
654 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
655 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
656 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
657 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200658 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200659
660 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200661 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200662 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
663 key_sts := ?)) {
664 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
665 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200666 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200667 }
668 }
Harald Welte76dee092018-02-16 22:12:59 +0100669 } else {
670 /* wait for identity procedure */
671 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100672 }
Harald Welte76dee092018-02-16 22:12:59 +0100673
Harald Welte5ac31492018-02-15 20:39:13 +0100674 deactivate(di);
675}
676
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200677function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100678 g_pars.p_tmsi := p_tmsi;
679 /* update TLLI */
680 g_pars.tlli_old := g_pars.tlli;
681 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100682 if (is_gb(ran_index)) {
683 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
684 }
Harald Weltef70997d2018-02-17 10:11:19 +0100685}
686
Harald Welte04683d02018-02-16 22:43:45 +0100687function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
688 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100689 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200690 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100691 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200692 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200693 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100694 }
Harald Welte04683d02018-02-16 22:43:45 +0100695 g_pars.ra := aa.routingAreaIdentification;
696 if (ispresent(aa.allocatedPTMSI)) {
697 if (not g_pars.net.expect_ptmsi) {
698 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200699 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100700 }
Harald Weltef70997d2018-02-17 10:11:19 +0100701 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100702 }
703 if (ispresent(aa.msIdentity)) {
704 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200705 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100706 }
707 /* P-TMSI.sig */
708 if (ispresent(aa.ptmsiSignature)) {
709 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
710 }
711 /* updateTimer */
712 // aa.readyTimer
713 /* T3302, T3319, T3323, T3312_ext, T3324 */
714}
715
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200716function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100717 /* mandatory IE */
718 g_pars.ra := ra.routingAreaId;
719 if (ispresent(ra.allocatedPTMSI)) {
720 if (not g_pars.net.expect_ptmsi) {
721 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200722 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100723 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200724 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100725 }
726 if (ispresent(ra.msIdentity)) {
727 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200728 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100729 }
730 /* P-TMSI.sig */
731 if (ispresent(ra.ptmsiSignature)) {
732 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
733 }
734 /* updateTimer */
735 // aa.readyTimer
736 /* T3302, T3319, T3323, T3312_ext, T3324 */
737}
738
739
Harald Welte5a4fa042018-02-16 20:59:21 +0100740function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
741 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
742}
743
Harald Welte23178c52018-02-17 09:36:33 +0100744/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700745private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100746 if (ispresent(g_pars.p_tmsi)) {
747 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
748 } else {
749 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
750 }
751}
752
Harald Welte311ec272018-02-17 09:40:03 +0100753private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100754 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100755 /* Expect MSC to perform LU with HLR */
756 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100757 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
758 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
759 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100760 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
761 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
762}
763
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200764friend 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 +0100765 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200766 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 +0200767 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100768
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200769 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
770 * 3G auth vectors */
771 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
772 /* The thing is, if the solSACapability is 'omit', then the
773 * revisionLevelIndicatior is at the wrong place! */
774 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
775
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200776 f_send_l3(attach_req, ran_index);
777 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200778 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100779 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100780
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200781 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200782 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
783
Harald Welte04683d02018-02-16 22:43:45 +0100784 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200785 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200786
787 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200788 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200789 as_iu_release_compl_disc();
790 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200791
792 /* Race condition
793 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
794 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
795 * arrived before it. This results in a test case failure.
796 * Delay execution by 50 ms
797 */
798 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200799}
800
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200801friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
802 timer T := 5.0;
803 var PDU_BSSGP rx_pdu;
804 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
805 T.start;
806 alt {
807 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
808 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
809 }
810 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
811 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
812 mtc.stop;
813 }
814 [] T.timeout {
815 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
816 mtc.stop;
817 }
818 }
819 return '00'O;
820}
821
822friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
823 timer T := 5.0;
824 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
825 T.start;
826 alt {
827 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
828 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
829?)) {
830 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
831 mtc.stop;
832 }
833 [] T.timeout {
834 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
835 mtc.stop;
836 }
837 }
838}
839
840
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200841private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
842 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100843 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100844}
845
846testcase TC_attach() runs on test_CT {
847 var BSSGP_ConnHdlr vc_conn;
848 f_init();
849 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200850 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100851 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200852 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100853}
854
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100855testcase TC_attach_mnc3() runs on test_CT {
856 var BSSGP_ConnHdlr vc_conn;
857 f_init('023042'H);
858 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200859 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100860 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200861 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100862}
863
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200864private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
865 f_gmm_attach(true, false);
866 setverdict(pass);
867}
868testcase TC_attach_umts_aka_umts_res() runs on test_CT {
869 var BSSGP_ConnHdlr vc_conn;
870 f_init();
871 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200872 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200873 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200874 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200875}
876
877private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
878 f_gmm_attach(true, true);
879 setverdict(pass);
880}
881testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
882 var BSSGP_ConnHdlr vc_conn;
883 f_init();
884 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200885 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200886 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200887 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200888}
889
Harald Welte5b7c8122018-02-16 21:48:17 +0100890/* MS never responds to ID REQ, expect ATTACH REJECT */
891private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100892 var RoutingAreaIdentificationV old_ra := f_random_RAI();
893
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200894 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100895 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200896 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100897 /* don't send ID Response */
898 repeat;
899 }
Harald Welte955aa942019-05-03 01:29:29 +0200900 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100901 setverdict(pass);
902 }
Harald Welte955aa942019-05-03 01:29:29 +0200903 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100904 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200905 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100906 }
907 }
908}
909testcase TC_attach_auth_id_timeout() runs on test_CT {
910 var BSSGP_ConnHdlr vc_conn;
911 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200912 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 +0100913 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200914 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100915}
916
917/* HLR never responds to SAI REQ, expect ATTACH REJECT */
918private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100919 var RoutingAreaIdentificationV old_ra := f_random_RAI();
920
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200921 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100922 alt {
923 [] as_mm_identity();
924 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
925 }
926 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200927 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100928 setverdict(pass);
929}
930testcase TC_attach_auth_sai_timeout() runs on test_CT {
931 var BSSGP_ConnHdlr vc_conn;
932 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200933 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100934 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200935 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100936}
937
Harald Weltefe253882018-02-17 09:25:00 +0100938/* HLR rejects SAI, expect ATTACH REJECT */
939private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100940 var RoutingAreaIdentificationV old_ra := f_random_RAI();
941
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200942 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100943 alt {
944 [] as_mm_identity();
945 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
946 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
947 }
948 }
Harald Welte955aa942019-05-03 01:29:29 +0200949 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100950 setverdict(pass);
951}
952testcase TC_attach_auth_sai_reject() runs on test_CT {
953 var BSSGP_ConnHdlr vc_conn;
954 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200955 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100956 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200957 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100958}
959
Harald Welte5b7c8122018-02-16 21:48:17 +0100960/* HLR never responds to UL REQ, expect ATTACH REJECT */
961private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200962 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100963 var RoutingAreaIdentificationV old_ra := f_random_RAI();
964
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200965 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100966 f_gmm_auth();
967 /* Expect MSC to perform LU with HLR */
968 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
969 /* Never follow-up with ISD_REQ or UL_RES */
970 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200971 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100972 setverdict(pass);
973 }
Harald Welte955aa942019-05-03 01:29:29 +0200974 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
975 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100976 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200977 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100978 }
979 }
980}
981testcase TC_attach_gsup_lu_timeout() runs on test_CT {
982 var BSSGP_ConnHdlr vc_conn;
983 f_init();
984 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200985 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100986 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200987 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100988}
989
Harald Welteb7c14e92018-02-17 09:29:16 +0100990/* HLR rejects UL REQ, expect ATTACH REJECT */
991private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200992 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100993 var RoutingAreaIdentificationV old_ra := f_random_RAI();
994
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200995 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100996 f_gmm_auth();
997 /* Expect MSC to perform LU with HLR */
998 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
999 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1000 }
1001 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001002 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001003 setverdict(pass);
1004 }
Harald Welte955aa942019-05-03 01:29:29 +02001005 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1006 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001007 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001008 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001009 }
1010 }
1011}
1012testcase TC_attach_gsup_lu_reject() runs on test_CT {
1013 var BSSGP_ConnHdlr vc_conn;
1014 f_init();
1015 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001016 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001017 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001018 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001019}
1020
1021
Harald Welte3823e2e2018-02-16 21:53:48 +01001022/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1023private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001024 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001025 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1026
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001027 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001028 f_gmm_auth();
1029 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001030 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001031
Harald Welte955aa942019-05-03 01:29:29 +02001032 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1033 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001034 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001035 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001036 setverdict(pass);
1037}
Harald Welte3823e2e2018-02-16 21:53:48 +01001038testcase TC_attach_combined() runs on test_CT {
1039 var BSSGP_ConnHdlr vc_conn;
1040 f_init();
1041 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001042 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001043 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001044 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001045}
1046
Harald Welte76dee092018-02-16 22:12:59 +01001047/* Attempt of GPRS ATTACH in 'accept all' mode */
1048private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001049 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001050 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1051
1052 g_pars.net.expect_auth := false;
1053
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001054 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001055 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001056 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1057 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001058 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001059 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001060 setverdict(pass);
1061}
1062testcase TC_attach_accept_all() runs on test_CT {
1063 var BSSGP_ConnHdlr vc_conn;
1064 f_init();
1065 f_sleep(1.0);
1066 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001067 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001068 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001069 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001070}
Harald Welte5b7c8122018-02-16 21:48:17 +01001071
Harald Welteb2124b22018-02-16 22:26:56 +01001072/* Attempt of GPRS ATTACH in 'accept all' mode */
1073private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001074 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1075
1076 /* Simulate a foreign IMSI */
1077 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001078 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001079
1080 g_pars.net.expect_auth := false;
1081
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001082 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001083 alt {
1084 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001085 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001086 setverdict(pass);
1087 }
Harald Welte955aa942019-05-03 01:29:29 +02001088 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001089 setverdict(pass);
1090 }
Harald Welte955aa942019-05-03 01:29:29 +02001091 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001092 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001093 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001094 }
Harald Welteb2124b22018-02-16 22:26:56 +01001095 }
1096}
1097testcase TC_attach_closed() runs on test_CT {
1098 var BSSGP_ConnHdlr vc_conn;
1099 f_init();
1100 f_sleep(1.0);
1101 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1102 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001103 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001104 vc_conn.done;
1105 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001106 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001107 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001108 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001109}
1110
Harald Welte04683d02018-02-16 22:43:45 +01001111/* Routing Area Update from Unknown TLLI -> REJECT */
1112private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001113 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1114
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001115 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 +01001116 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001117 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001118 setverdict(pass);
1119 }
1120 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001121 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001122 }
1123}
1124testcase TC_rau_unknown() runs on test_CT {
1125 var BSSGP_ConnHdlr vc_conn;
1126 f_init();
1127 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001128 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001129 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001130 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001131}
1132
Harald Welte91636de2018-02-17 10:16:14 +01001133private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001134 /* first perform regular attach */
1135 f_TC_attach(id);
1136
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001137 f_routing_area_update(g_pars.ra);
1138
Harald Welte91636de2018-02-17 10:16:14 +01001139}
1140testcase TC_attach_rau() runs on test_CT {
1141 var BSSGP_ConnHdlr vc_conn;
1142 f_init();
1143 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001144 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001145 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001146 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001147}
Harald Welte04683d02018-02-16 22:43:45 +01001148
Harald Welte6abb9fe2018-02-17 15:24:48 +01001149/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001150function 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 +02001151 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001152 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001153 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001154 if (expect_purge) {
1155 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1156 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1157 }
1158 T.start;
1159 alt {
1160 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1161 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001162 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001163 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001164 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001165 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001166 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001167 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001168 /* TODO: check if any PDP contexts are deactivated on network side? */
1169 }
1170 [power_off] T.timeout {
1171 setverdict(pass);
1172 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001173 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001174 g_pars.ra := omit;
1175 setverdict(pass);
1176 /* TODO: check if any PDP contexts are deactivated on network side? */
1177 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001178 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001179 if (power_off) {
1180 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1181 } else {
1182 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1183 }
1184 mtc.stop;
1185 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001186 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001187 }
1188}
1189
1190/* IMSI DETACH (non-power-off) for unknown TLLI */
1191private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1192 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1193}
1194testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1195 var BSSGP_ConnHdlr vc_conn;
1196 f_init();
1197 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001198 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001199 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001200 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001201}
1202
1203/* IMSI DETACH (power-off) for unknown TLLI */
1204private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1205 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1206}
1207testcase TC_detach_unknown_poweroff() runs on test_CT {
1208 var BSSGP_ConnHdlr vc_conn;
1209 f_init();
1210 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001211 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001212 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001213 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001214}
1215
1216/* IMSI DETACH (non-power-off) for known TLLI */
1217private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1218 /* first perform regular attach */
1219 f_TC_attach(id);
1220
1221 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1222}
1223testcase TC_detach_nopoweroff() runs on test_CT {
1224 var BSSGP_ConnHdlr vc_conn;
1225 f_init();
1226 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001227 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001228 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001229 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001230}
1231
1232/* IMSI DETACH (power-off) for known TLLI */
1233private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1234 /* first perform regular attach */
1235 f_TC_attach(id);
1236
1237 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1238}
1239testcase TC_detach_poweroff() runs on test_CT {
1240 var BSSGP_ConnHdlr vc_conn;
1241 f_init();
1242 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001243 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001244 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001245 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001246}
1247
Harald Welteeded9ad2018-02-17 20:57:34 +01001248type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001249 BIT3 tid, /* L3 Transaction ID */
1250 BIT4 nsapi, /* SNDCP NSAPI */
1251 BIT4 sapi, /* LLC SAPI */
1252 QoSV qos, /* QoS parameters */
1253 PDPAddressV addr, /* IP address */
1254 octetstring apn optional, /* APN name */
1255 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1256 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001257 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001258 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001259
Harald Welte822f9102018-02-18 20:39:06 +01001260 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1261 OCT4 ggsn_tei_u, /* GGSN TEI User */
1262 octetstring ggsn_ip_c, /* GGSN IP Control */
1263 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001264 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001265
Harald Welte822f9102018-02-18 20:39:06 +01001266 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1267 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1268 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1269 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001270};
1271
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001272
1273private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1274 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1275 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1276 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1277 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1278 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1279 f_gtp_register_teid(apars.ggsn_tei_c);
1280 f_gtp_register_teid(apars.ggsn_tei_u);
1281}
1282
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001283function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001284runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001285 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1286 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001287 var template Recovery_gtpc recovery := omit;
1288
1289 if (send_recovery) {
1290 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1291 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001292
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001293 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 +02001294 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001295 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1296 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1297 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1298 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1299 apars.sgsn_tei_c, apars.gtp_resp_cause,
1300 apars.ggsn_tei_c, apars.ggsn_tei_u,
1301 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001302 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1303 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001304 }
1305 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001306 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001307 setverdict(pass);
1308 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001309 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001310 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001311 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001312 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001313 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001314 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
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 Weltef7191672019-05-02 20:37:23 +02001318 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1319 mtc.stop;
1320 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001321 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001322 setverdict(pass);
1323 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001324 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001325 }
1326}
1327
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001328function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001329runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001330 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1331 var Gtp1cUnitdata g_ud;
1332
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001333 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001334 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1335 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001336 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001337 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1338 }
1339 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001340 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001341 setverdict(pass);
1342 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001343 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001344 }
1345}
1346
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001347function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001348runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001349 var Gtp1cUnitdata g_ud;
1350 var integer seq_nr := 23;
1351 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1352
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001353 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001354 if (error_ind) {
1355 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1356 } else {
1357 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1358 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001359
1360 timer T := 5.0;
1361 T.start;
1362
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001363 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001364 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1365 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001366 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001367 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1368 repeat;
1369 }
1370 [] T.timeout {
1371 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1372 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001373 }
1374}
1375
Harald Welte6f203162018-02-18 22:04:55 +01001376
Harald Welteeded9ad2018-02-17 20:57:34 +01001377/* Table 10.5.156/3GPP TS 24.008 */
1378template (value) QoSV t_QosDefault := {
1379 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1380 delayClass := '100'B, /* best effort */
1381 spare1 := '00'B,
1382 precedenceClass := '010'B, /* normal */
1383 spare2 := '0'B,
1384 peakThroughput := '0000'B, /* subscribed */
1385 meanThroughput := '00000'B, /* subscribed */
1386 spare3 := '000'B,
1387 deliverErroneusSDU := omit,
1388 deliveryOrder := omit,
1389 trafficClass := omit,
1390 maxSDUSize := omit,
1391 maxBitrateUplink := omit,
1392 maxBitrateDownlink := omit,
1393 sduErrorRatio := omit,
1394 residualBER := omit,
1395 trafficHandlingPriority := omit,
1396 transferDelay := omit,
1397 guaranteedBitRateUplink := omit,
1398 guaranteedBitRateDownlink := omit,
1399 sourceStatisticsDescriptor := omit,
1400 signallingIndication := omit,
1401 spare4 := omit,
1402 maxBitrateDownlinkExt := omit,
1403 guaranteedBitRateDownlinkExt := omit,
1404 maxBitrateUplinkExt := omit,
1405 guaranteedBitRateUplinkExt := omit,
1406 maxBitrateDownlinkExt2 := omit,
1407 guaranteedBitRateDownlinkExt2 := omit,
1408 maxBitrateUplinkExt2 := omit,
1409 guaranteedBitRateUplinkExt2 := omit
1410}
1411
1412/* 10.5.6.4 / 3GPP TS 24.008 */
1413template (value) PDPAddressV t_AddrIPv4dyn := {
1414 pdpTypeOrg := '0001'B, /* IETF */
1415 spare := '0000'B,
1416 pdpTypeNum := '21'O, /* IPv4 */
1417 addressInfo := omit
1418}
1419template (value) PDPAddressV t_AddrIPv6dyn := {
1420 pdpTypeOrg := '0001'B, /* IETF */
1421 spare := '0000'B,
1422 pdpTypeNum := '53'O, /* IPv6 */
1423 addressInfo := omit
1424}
1425
Harald Welte37692d82018-02-18 15:21:34 +01001426template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001427 tid := '000'B,
1428 nsapi := '0101'B, /* < 5 are reserved */
1429 sapi := '0011'B, /* 3/5/9/11 */
1430 qos := t_QosDefault,
1431 addr := t_AddrIPv4dyn,
1432 apn := omit,
1433 pco := omit,
1434 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001435 gtp_resp_cause := int2oct(128, 1),
1436 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001437
1438 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001439 ggsn_tei_c := f_rnd_octstring(4),
1440 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001441 ggsn_ip_c := f_inet_addr(ggsn_ip),
1442 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001443 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001444
Harald Welteeded9ad2018-02-17 20:57:34 +01001445 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001446 sgsn_tei_u := omit,
1447 sgsn_ip_c := omit,
1448 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001449}
1450
Harald Welte37692d82018-02-18 15:21:34 +01001451template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1452 connId := 1,
1453 remName := f_inet_ntoa(ip),
1454 remPort := GTP1U_PORT
1455}
1456
1457template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1458 connId := 1,
1459 remName := f_inet_ntoa(ip),
1460 remPort := GTP1C_PORT
1461}
1462
1463private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1464 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1465 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1466}
1467
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001468private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1469 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001470 repeat;
1471 }
1472}
1473
1474template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1475 pDU_SN_UNITDATA := {
1476 nsapi := nsapi,
1477 moreBit := ?,
1478 snPduType := '1'B,
1479 firstSegmentIndicator := ?,
1480 spareBit := ?,
1481 pcomp := ?,
1482 dcomp := ?,
1483 npduNumber := ?,
1484 segmentNumber := ?,
1485 npduNumberContinued := ?,
1486 dataSegmentSnUnitdataPdu := payload
1487 }
1488}
1489
1490/* simple case: single segment, no compression */
1491template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1492 pDU_SN_UNITDATA := {
1493 nsapi := nsapi,
1494 moreBit := '0'B,
1495 snPduType := '1'B,
1496 firstSegmentIndicator := '1'B,
1497 spareBit := '0'B,
1498 pcomp := '0000'B,
1499 dcomp := '0000'B,
1500 npduNumber := '0000'B,
1501 segmentNumber := '0000'B,
1502 npduNumberContinued := '00'O,
1503 dataSegmentSnUnitdataPdu := payload
1504 }
1505}
1506
1507/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001508private 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 +02001509runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001510 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001511 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1512 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001513 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001514 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1515 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001516 [] as_xid(apars, ran_index);
1517 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001518 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1519 [expect_fwd] T.timeout {
1520 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1521 mtc.stop;
1522 }
1523 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1524 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1525 mtc.stop;
1526 }
1527 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001528 }
1529}
1530
Harald Welte64d6b512020-06-17 16:42:00 +02001531/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001532private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001533runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001534 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1535 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1536 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001537 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001538 /* Expect PDU via GTP from SGSN on simulated GGSN */
1539 alt {
1540 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1541 }
1542}
1543
Harald Welteeded9ad2018-02-17 20:57:34 +01001544private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001545 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001546
1547 /* first perform regular attach */
1548 f_TC_attach(id);
1549
1550 f_pdp_ctx_act(apars);
1551}
1552testcase TC_attach_pdp_act() runs on test_CT {
1553 var BSSGP_ConnHdlr vc_conn;
1554 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001555 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001556 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001557 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001558}
Harald Welteb2124b22018-02-16 22:26:56 +01001559
Harald Welte835b15f2018-02-18 14:39:11 +01001560/* PDP Context activation for not-attached subscriber; expect fail */
1561private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001562 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001563 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 +01001564 apars.apn, apars.pco));
1565 alt {
1566 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001567 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001568 setverdict(pass);
1569 }
1570 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1571 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001572 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001573 }
Harald Welte955aa942019-05-03 01:29:29 +02001574 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001575 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001576 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001577 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001578 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001579 }
1580}
1581testcase TC_pdp_act_unattached() runs on test_CT {
1582 var BSSGP_ConnHdlr vc_conn;
1583 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001584 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001585 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001586 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001587}
1588
Harald Welte37692d82018-02-18 15:21:34 +01001589/* ATTACH + PDP CTX ACT + user plane traffic */
1590private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1591 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1592
1593 /* first perform regular attach */
1594 f_TC_attach(id);
1595 /* then activate PDP context */
1596 f_pdp_ctx_act(apars);
1597 /* then transceive a downlink PDU */
1598 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1599 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1600}
1601testcase TC_attach_pdp_act_user() runs on test_CT {
1602 var BSSGP_ConnHdlr vc_conn;
1603 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001604 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001605 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001606 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001607}
1608
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001609/* ATTACH + PDP CTX ACT; reject from GGSN */
1610private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1611 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1612
1613 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1614 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1615
1616 /* first perform regular attach */
1617 f_TC_attach(id);
1618 /* then activate PDP context */
1619 f_pdp_ctx_act(apars);
1620}
1621testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1622 var BSSGP_ConnHdlr vc_conn;
1623 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001624 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001625 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001626 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001627}
Harald Welte835b15f2018-02-18 14:39:11 +01001628
Harald Welte6f203162018-02-18 22:04:55 +01001629/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1630private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1631 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1632
1633 /* first perform regular attach */
1634 f_TC_attach(id);
1635 /* then activate PDP context */
1636 f_pdp_ctx_act(apars);
1637 /* then transceive a downlink PDU */
1638 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1639 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1640
1641 f_pdp_ctx_deact_mo(apars, '00'O);
1642}
1643testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1644 var BSSGP_ConnHdlr vc_conn;
1645 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001646 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 +01001647 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001648 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001649}
1650
Harald Welte57b9b7f2018-02-18 22:28:13 +01001651/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1652private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1653 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1654
1655 /* first perform regular attach */
1656 f_TC_attach(id);
1657 /* then activate PDP context */
1658 f_pdp_ctx_act(apars);
1659 /* then transceive a downlink PDU */
1660 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1661 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1662
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001663 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001664}
1665testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1666 var BSSGP_ConnHdlr vc_conn;
1667 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001668 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 +01001669 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001670 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001671}
1672
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001673/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1674private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1675 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1676 var Gtp1cUnitdata g_ud;
1677 var integer i;
1678 var OCT1 cause_regular_deact := '24'O;
1679
1680 /* first perform regular attach + PDP context act */
1681 f_TC_attach(id);
1682 f_pdp_ctx_act(apars);
1683
1684 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1685 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1686
1687 for (i := 0; i < 2; i := i+1) {
1688 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1689 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1690 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1691 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1692 }
1693 }
1694
1695 alt {
1696 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1697 setverdict(pass);
1698 }
1699 [] as_xid(apars, 0);
1700 }
1701
1702 /* Make sure second DeactPdpAccept is sent: */
1703 timer T := 2.0;
1704 T.start;
1705 alt {
1706 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1707 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1708 }
1709 [] T.timeout {
1710 setverdict(pass);
1711 }
1712 }
1713
1714 setverdict(pass);
1715}
1716testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1717 var BSSGP_ConnHdlr vc_conn;
1718 f_init();
1719 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1720 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001721 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001722}
1723
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001724/* ATTACH + ATTACH (2nd) */
1725private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1726 g_pars.t_guard := 5.0;
1727
1728 /* first perform regular attach */
1729 f_TC_attach(id);
1730
1731 /* second to perform regular attach */
1732 f_TC_attach(id);
1733}
1734
1735
1736testcase TC_attach_second_attempt() runs on test_CT {
1737 var BSSGP_ConnHdlr vc_conn;
1738 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001739 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001740 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001741 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001742}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001743
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001744private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1745 var Gtp1cUnitdata g_ud;
1746 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1747 var integer seq_nr;
1748
1749 /* first perform regular attach */
1750 f_TC_attach(id);
1751 /* then activate PDP context */
1752 f_pdp_ctx_act(apars);
1753
1754 /* Wait to receive first echo request and send initial Restart counter */
1755 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1756 BSSGP[0].clear;
1757 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1758 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1759 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1760 }
1761
1762 /* At some point next echo request not answered will timeout and SGSN
1763 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1764 timer T := 3.0 * 6.0 + 16.0;
1765 T.start;
1766 alt {
1767 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1768 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1769 setverdict(pass);
1770 }
1771 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1772 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1773 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1774 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1775 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1776 repeat;
1777 }
1778 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1779 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1780 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1781 repeat;
1782 }
1783 [] T.timeout {
1784 setverdict(fail, "BSSGP DeactPdpReq not received");
1785 mtc.stop;
1786 }
1787 [] as_xid(apars);
1788 }
1789 T.stop
1790
1791 setverdict(pass);
1792}
1793/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1794testcase TC_attach_echo_timeout() runs on test_CT {
1795 var BSSGP_ConnHdlr vc_conn;
1796 g_use_echo := true;
1797 f_init();
1798 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1799 vc_conn.done;
1800 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001801 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001802}
1803
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001804private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001805 var Gtp1cUnitdata g_ud;
1806 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1807
1808 /* first perform regular attach */
1809 f_TC_attach(id);
1810 /* Activate a pdp context against the GGSN */
1811 f_pdp_ctx_act(apars);
1812 /* Wait to receive first echo request and send initial Restart counter */
1813 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1814 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1815 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1816 }
1817 /* Wait to receive second echo request and send incremented Restart
1818 counter. This will fake a restarted GGSN, and pdp ctx allocated
1819 should be released by SGSN */
1820 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1821 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1822 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1823 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1824 }
1825 var OCT1 cause_network_failure := int2oct(38, 1)
1826 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001827 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001828 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001829 setverdict(pass);
1830 }
1831 [] as_xid(apars);
1832 }
1833 setverdict(pass);
1834}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001835/* ATTACH + trigger Recovery procedure through EchoResp */
1836testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001837 var BSSGP_ConnHdlr vc_conn;
1838 g_use_echo := true
1839 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001840 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 +02001841 vc_conn.done;
1842 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001843 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001844}
1845
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001846private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1847 var Gtp1cUnitdata g_ud;
1848 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1849 var integer seq_nr := 23;
1850 var GtpPeer peer;
1851 /* first perform regular attach */
1852 f_TC_attach(id);
1853
1854 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1855 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1856 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1857 f_pdp_ctx_act(apars, true);
1858
1859 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1860/* received. */
1861 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1862
1863 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1864 would be great to have an active pdp context here before triggering
1865 Recovery, and making sure the the DEACT request is sent by the SGSN.
1866 */
1867
1868 /* Activate a pdp context against the GGSN, send incremented Recovery
1869 IE. This should trigger the recovery path, but still this specific
1870 CTX activation should work. */
1871 apars.exp_rej_cause := omit; /* default value for tests */
1872 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1873 f_pdp_ctx_act(apars, true);
1874
1875 setverdict(pass);
1876}
1877/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1878testcase TC_attach_restart_ctr_create() runs on test_CT {
1879 var BSSGP_ConnHdlr vc_conn;
1880 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001881 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 +02001882 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001883 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001884}
1885
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001886/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1887private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1888 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1889 var integer seq_nr := 23;
1890 var GtpPeer peer;
1891 var integer i;
1892
1893 /* first perform regular attach */
1894 f_TC_attach(id);
1895 /* then activate PDP context */
1896 f_pdp_ctx_act(apars);
1897
Alexander Couzens0e510e62018-07-28 23:06:00 +02001898 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001899 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1900 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1901
1902 for (i := 0; i < 5; i := i+1) {
1903 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001904 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001905 [] as_xid(apars);
1906 }
1907 }
1908
1909 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1910
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001911 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001912 setverdict(pass);
1913}
1914testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1915 var BSSGP_ConnHdlr vc_conn;
1916 f_init();
1917 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001918 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 +02001919 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001920 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001921}
1922
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001923/* ATTACH + PDP CTX ACT dropped + retrans */
1924private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1925 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1926 var Gtp1cUnitdata g_ud_first, g_ud_second;
1927 /* first perform regular attach */
1928 f_TC_attach(id);
1929
1930 /* then activate PDP context on the Gb side */
1931 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1932 apars.apn, apars.pco), 0);
1933
1934 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1935 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1936 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1937 if (g_ud_first != g_ud_second) {
1938 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1939 mtc.stop;
1940 }
1941 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1942 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1943 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1944 apars.sgsn_tei_c, apars.gtp_resp_cause,
1945 apars.ggsn_tei_c, apars.ggsn_tei_u,
1946 apars.nsapi,
1947 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1948 omit, omit));
1949 }
Harald Welte955aa942019-05-03 01:29:29 +02001950 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001951
1952 /* Now the same with Deact */
1953 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1954 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1955 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1956 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1957 if (g_ud_first != g_ud_second) {
1958 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1959 mtc.stop;
1960 }
1961 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1962 BSSGP[0].clear;
1963 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1964 }
1965 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001966 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001967 setverdict(pass);
1968 }
1969 [] as_xid(apars, 0);
1970 }
1971
1972 setverdict(pass);
1973}
1974testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1975 var BSSGP_ConnHdlr vc_conn;
1976 f_init();
1977 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1978 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001979 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001980}
1981
1982/* Test that SGSN GTP response retransmit queue works fine */
1983private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1984 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1985 var integer seq_nr := 23;
1986 var Gtp1cUnitdata g_ud_first, g_ud_second;
1987 var template Gtp1cUnitdata g_delete_req;
1988 /* first perform regular attach + PDP context act */
1989 f_TC_attach(id);
1990 f_pdp_ctx_act(apars);
1991
1992 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1993 BSSGP[0].clear;
1994 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1995 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1996 GTP.send(g_delete_req);
1997 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001998 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001999 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2000 }
2001 [] as_xid(apars, 0);
2002 }
2003 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2004 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2005 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2006 mtc.stop;
2007 }
2008 };
2009
2010 /* Send duplicate DeleteCtxReq */
2011 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2012 GTP.send(g_delete_req);
2013 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2014 if (g_ud_first != g_ud_second) {
2015 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2016 mtc.stop;
2017 }
2018 }
2019
2020 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2021 * is handled differently by SGSN (expect "non-existent" cause) */
2022 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2023 GTP.send(g_delete_req);
2024 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2025 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2026 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2027 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2028 mtc.stop;
2029 }
2030 }
2031
2032 setverdict(pass);
2033}
2034testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2035 var BSSGP_ConnHdlr vc_conn;
2036 f_init();
2037 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2038 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002039 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002040}
2041
Alexander Couzens5e307b42018-05-22 18:12:20 +02002042private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2043 /* MS: perform regular attach */
2044 f_TC_attach(id);
2045
2046 /* HLR: cancel the location request */
2047 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2048 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002049
2050 /* ensure no Detach Request got received */
2051 timer T := 5.0;
2052 T.start;
2053 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002054 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002055 T.stop;
2056 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002057 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002058 }
2059 [] T.timeout {
2060 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002061 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002062 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002063 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002064 repeat;
2065 }
2066 }
2067}
2068
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002069/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2070private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2071 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2072
2073 /* first perform regular attach */
2074 f_TC_attach(id);
2075 /* then activate PDP context */
2076 f_pdp_ctx_act(apars);
2077 /* then transceive a downlink PDU */
2078 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2079
2080 /* Send Error indication as response from upload PDU and expect deact towards MS */
2081 f_pdp_ctx_deact_mt(apars, true);
2082}
2083testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2084 var BSSGP_ConnHdlr vc_conn;
2085 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002086 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 +02002087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002088 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002089}
2090
Alexander Couzens5e307b42018-05-22 18:12:20 +02002091testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2092 /* MS <-> SGSN: GMM Attach
2093 * HLR -> SGSN: Cancel Location Request
2094 * HLR <- SGSN: Cancel Location Ack
2095 */
2096 var BSSGP_ConnHdlr vc_conn;
2097 f_init();
2098 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002099 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002100 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002101 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002102}
2103
2104
Alexander Couzensc87967a2018-05-22 16:09:54 +02002105private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2106 /* MS: perform regular attach */
2107 f_TC_attach(id);
2108
2109 /* HLR: cancel the location request */
2110 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2111 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2112 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2113
2114 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002115 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002116 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002117
2118 setverdict(pass);
2119}
2120
2121testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2122 /* MS <-> SGSN: GMM Attach
2123 * HLR -> SGSN: Cancel Location Request
2124 * HLR <- SGSN: Cancel Location Ack
2125 * MS <- SGSN: Detach Request
2126 * SGSN-> MS: Detach Complete
2127 */
2128 var BSSGP_ConnHdlr vc_conn;
2129 f_init();
2130 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002131 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002132 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002133 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002134}
2135
2136
Alexander Couzens6c47f292018-05-22 17:09:49 +02002137private function f_hlr_location_cancel_request_unknown_subscriber(
2138 charstring id,
2139 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2140
2141 /* HLR: cancel the location request */
2142 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2143
2144 /* cause 2 = IMSI_UNKNOWN */
2145 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2146
2147 setverdict(pass);
2148}
2149
2150private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002151 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002152}
2153
2154testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2155 /* HLR -> SGSN: Cancel Location Request
2156 * HLR <- SGSN: Cancel Location Error
2157 */
2158
2159 var BSSGP_ConnHdlr vc_conn;
2160 f_init();
2161 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002162 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 +02002163 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002164 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002165}
2166
2167private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002168 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002169}
2170
2171testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2172 /* HLR -> SGSN: Cancel Location Request
2173 * HLR <- SGSN: Cancel Location Error
2174 */
2175
2176 var BSSGP_ConnHdlr vc_conn;
2177 f_init();
2178 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002179 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 +02002180 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002181 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002182}
2183
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002184private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2185 f_TC_attach(id);
2186 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2187}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002188
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002189testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2190 /* MS <-> SGSN: Attach
2191 * MS -> SGSN: Detach Req (Power off)
2192 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2193 */
2194 var BSSGP_ConnHdlr vc_conn;
2195 var integer id := 33;
2196 var charstring imsi := hex2str(f_gen_imsi(id));
2197
2198 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002199 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002200 vc_conn.done;
2201
2202 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002203 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002204}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002205
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002206/* Attempt an attach, but loose the Identification Request (IMEI) */
2207private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2208 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002209 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002210
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002211 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 +02002212
2213 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002214 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002215 /* break */
2216 }
Harald Welte955aa942019-05-03 01:29:29 +02002217 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002218 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002219 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002220 repeat;
2221 }
Harald Welte955aa942019-05-03 01:29:29 +02002222 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002223 /* ignore ID REQ IMEI */
2224 count_req := count_req + 1;
2225 repeat;
2226 }
2227 }
2228 if (count_req != 5) {
2229 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002230 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002231 }
2232 setverdict(pass);
2233}
2234
2235testcase TC_attach_no_imei_response() runs on test_CT {
2236 /* MS -> SGSN: Attach Request IMSI
2237 * MS <- SGSN: Identity Request IMSI (optional)
2238 * MS -> SGSN: Identity Response IMSI (optional)
2239 * MS <- SGSN: Identity Request IMEI
2240 * MS -x SGSN: no response
2241 * MS <- SGSN: re-send: Identity Request IMEI 4x
2242 * MS <- SGSN: Attach Reject
2243 */
2244 var BSSGP_ConnHdlr vc_conn;
2245 f_init();
2246 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002247 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 +02002248 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002249 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002250}
2251
Alexander Couzens53f20562018-06-12 16:24:12 +02002252/* Attempt an attach, but loose the Identification Request (IMSI) */
2253private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2254 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002255 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002256
2257 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2258 g_pars.p_tmsi := 'c0000035'O;
2259
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002260 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 +02002261
2262 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002263 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002264 /* break */
2265 }
Harald Welte955aa942019-05-03 01:29:29 +02002266 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002267 /* ignore ID REQ IMSI */
2268 count_req := count_req + 1;
2269 repeat;
2270 }
Harald Welte955aa942019-05-03 01:29:29 +02002271 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002272 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002273 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002274 repeat;
2275 }
2276 }
2277 if (count_req != 5) {
2278 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002279 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002280 }
2281 setverdict(pass);
2282}
2283
2284testcase TC_attach_no_imsi_response() runs on test_CT {
2285 /* MS -> SGSN: Attach Request TMSI (unknown)
2286 * MS <- SGSN: Identity Request IMEI (optional)
2287 * MS -> SGSN: Identity Response IMEI (optional)
2288 * MS <- SGSN: Identity Request IMSI
2289 * MS -x SGSN: no response
2290 * MS <- SGSN: re-send: Identity Request IMSI 4x
2291 * MS <- SGSN: Attach Reject
2292 */
2293 var BSSGP_ConnHdlr vc_conn;
2294 f_init();
2295 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002296 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 +02002297 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002298 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002299}
2300
Alexander Couzenscf818962018-06-05 18:00:00 +02002301private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2302 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2303}
2304
2305testcase TC_attach_check_subscriber_list() runs on test_CT {
2306 /* MS <-> SGSN: Attach
2307 * VTY -> SGSN: Check if MS is in subscriber cache
2308 */
2309 var BSSGP_ConnHdlr vc_conn;
2310 var integer id := 34;
2311 var charstring imsi := hex2str(f_gen_imsi(id));
2312
2313 f_init();
2314 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002315 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002316 vc_conn.done;
2317
2318 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2319 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002320 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002321}
2322
Alexander Couzensf9858652018-06-07 16:14:53 +02002323private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2324 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002325 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002326
2327 /* unregister the old IMSI */
2328 f_bssgp_client_unregister(g_pars.imsi);
2329 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002330 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002331 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002332
2333 /* there is no auth */
2334 g_pars.net.expect_auth := false;
2335
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002336 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002337 f_gmm_auth();
2338 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002339 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002340 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002341 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002342 }
Harald Welte955aa942019-05-03 01:29:29 +02002343 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2344 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002345 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002346 setverdict(pass);
2347 }
2348 }
2349}
Alexander Couzens03d12242018-08-07 16:13:52 +02002350
2351private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2352
2353 f_TC_attach_closed_foreign(id);
2354 f_TC_attach_closed_imsi_added(id);
2355
2356}
2357
2358
Alexander Couzensf9858652018-06-07 16:14:53 +02002359testcase TC_attach_closed_add_vty() runs on test_CT {
2360 /* VTY-> SGSN: policy close
2361 * MS -> SGSN: Attach Request
2362 * MS <- SGSN: Identity Request IMSI
2363 * MS -> SGSN: Identity Response IMSI
2364 * MS <- SGSN: Attach Reject
2365 * VTY-> SGSN: policy imsi-acl add IMSI
2366 * MS -> SGSN: Attach Request
2367 * MS <- SGSN: Identity Request IMSI
2368 * MS -> SGSN: Identity Response IMSI
2369 * MS <- SGSN: Identity Request IMEI
2370 * MS -> SGSN: Identity Response IMEI
2371 * MS <- SGSN: Attach Accept
2372 */
2373 var BSSGP_ConnHdlr vc_conn;
2374 f_init();
2375 f_sleep(1.0);
2376 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2377 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002378 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2379 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002380 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002381 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002382 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002383 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002384}
2385
Alexander Couzens0085bd72018-06-12 19:08:44 +02002386/* Attempt an attach, but never answer a Attach Complete */
2387private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2388 var integer count_req := 0;
2389
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002390 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 +02002391 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002392 /* Expect SGSN to perform LU with HLR */
2393 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002394
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002395 timer T := 10.0;
2396 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002397 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002398 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002399 /* break */
2400 }
Harald Welte955aa942019-05-03 01:29:29 +02002401 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002402 /* ignore */
2403 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002404 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002405 repeat;
2406 }
2407 }
2408 if (count_req != 5) {
2409 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002410 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002411 }
2412 setverdict(pass);
2413}
2414
2415testcase TC_attach_check_complete_resend() runs on test_CT {
2416 /* MS -> SGSN: Attach Request IMSI
2417 * MS <- SGSN: Identity Request *
2418 * MS -> SGSN: Identity Response *
2419 * MS <- SGSN: Attach Complete 5x
2420 */
2421 var BSSGP_ConnHdlr vc_conn;
2422 f_init();
2423 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002424 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 +02002425 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002426 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002427}
2428
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002429friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002430 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002431 var PDU_DTAP_PS_MT mt;
2432 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002433
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002434 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002435 p_tmsi := g_pars.p_tmsi;
2436 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002437 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002438 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 +02002439 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002440 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2441 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2442 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002443 setverdict(pass);
2444 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002445 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2446 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2447 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002448 setverdict(pass);
2449 }
2450
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002451 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002452 setverdict(fail, "Unexpected RAU Reject");
2453 mtc.stop;
2454 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002455 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002456 setverdict(fail, "Unexpected RAU Reject");
2457 mtc.stop;
2458 }
2459
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002460 [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 +02002461 key_sts := ?)) {
2462 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2463 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002464 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002465 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002466 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002467 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2468 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002469 }
2470}
2471
Alexander Couzensbfda9212018-07-31 03:17:33 +02002472private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002473 /* first perform regular attach */
2474 f_TC_attach(id);
2475
2476 /* then send RAU */
2477 f_routing_area_update(g_pars.ra);
2478
2479 /* do another RAU */
2480 f_routing_area_update(g_pars.ra);
2481
2482 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2483}
2484
2485testcase TC_attach_rau_a_a() runs on test_CT {
2486 /* MS <-> SGSN: Successful Attach
2487 * MS -> SGSN: Routing Area Update Request
2488 * MS <- SGSN: Routing Area Update Accept
2489 * MS -> SGSN: Routing Area Update Request
2490 * MS <- SGSN: Routing Area Update Accept
2491 * MS -> SGSN: Detach (PowerOff)
2492 */
2493 var BSSGP_ConnHdlr vc_conn;
2494 f_init();
2495 f_sleep(1.0);
2496 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2497 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002498 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002499}
2500
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002501private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002502 f_TC_attach(id);
2503
2504 log("attach complete sending rau");
2505 f_routing_area_update(g_pars.ra, 0);
2506
2507 log("rau complete unregistering");
2508 f_bssgp_client_unregister(g_pars.imsi);
2509 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2510
2511 log("sending second RAU via different RA");
2512 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2513
2514 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2515}
2516
2517testcase TC_attach_rau_a_b() runs on test_CT {
2518 /* MS <-> SGSN: Successful Attach
2519 * MS -> SGSN: Routing Area _a_ Update Request
2520 * MS <- SGSN: Routing Area _a_ Update Accept
2521 * MS -> SGSN: Routing Area _b_ Update Request
2522 * MS <- SGSN: Routing Area _b_ Update Accept
2523 * MS -> SGSN: Detach (PowerOff)
2524 */
2525 var BSSGP_ConnHdlr vc_conn;
2526 f_init();
2527 f_sleep(1.0);
2528 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2529 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002530 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002531}
2532
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002533private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2534 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002535 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002536 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002537 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002538
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002539 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002540
2541 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002542 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002543 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2544 mtc.stop;
2545 }
Harald Welte955aa942019-05-03 01:29:29 +02002546 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002547 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002548 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002549 repeat;
2550 }
Harald Welte955aa942019-05-03 01:29:29 +02002551 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002552 /* send out a second GMM_Attach Request.
2553 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2554 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002555 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002556 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002557 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002558 }
2559 }
2560 f_sleep(1.0);
2561
2562 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2563 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002564 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002565 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002566 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002567 repeat;
2568 }
Harald Welte955aa942019-05-03 01:29:29 +02002569 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002570 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2571 mtc.stop;
2572 }
Harald Welte955aa942019-05-03 01:29:29 +02002573 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002574 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2575 mtc.stop;
2576 }
Harald Welte955aa942019-05-03 01:29:29 +02002577 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2578 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002579 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002580 setverdict(pass);
2581 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2582 }
2583 }
2584}
2585
2586testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2587 /* Testing if the SGSN ignore Attach Request with the exact same content */
2588 /* MS -> SGSN: Attach Request IMSI
2589 * MS <- SGSN: Identity Request IMSI (optional)
2590 * MS -> SGSN: Identity Response IMSI (optional)
2591 * MS <- SGSN: Identity Request IMEI
2592 * MS -> SGSN: Attach Request (2nd)
2593 * MS <- SGSN: Identity Response IMEI
2594 * MS <- SGSN: Attach Accept
2595 * MS -> SGSN: Attach Complete
2596 */
2597 var BSSGP_ConnHdlr vc_conn;
2598 f_init();
2599 f_sleep(1.0);
2600 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2601 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2602 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002603 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002604}
2605
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002606private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002607 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2608
2609 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2610
2611 /* send Attach Request */
2612 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2613 * 3G auth vectors */
2614 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2615 /* The thing is, if the solSACapability is 'omit', then the
2616 * revisionLevelIndicatior is at the wrong place! */
2617 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002618 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002619
2620 /* do the auth */
2621 var PDU_L3_MS_SGSN l3_mo;
2622 var PDU_L3_SGSN_MS l3_mt;
2623 var default di := activate(as_mm_identity());
2624
2625 var GSUP_IE auth_tuple;
2626 var template AuthenticationParameterAUTNTLV autn;
2627
2628 g_pars.vec := f_gen_auth_vec_3g();
2629 autn := {
2630 elementIdentifier := '28'O,
2631 lengthIndicator := lengthof(g_pars.vec.autn),
2632 autnValue := g_pars.vec.autn
2633 };
2634 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2635 g_pars.vec.sres,
2636 g_pars.vec.kc,
2637 g_pars.vec.ik,
2638 g_pars.vec.ck,
2639 g_pars.vec.autn,
2640 g_pars.vec.res));
2641 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2642 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2643 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2644
2645 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2646 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002647 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002648
2649 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002650 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002651
2652 /* wait for the GSUP resync request */
2653 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2654 g_pars.imsi,
2655 g_pars.vec.auts,
2656 g_pars.vec.rand));
2657
2658 /* generate new key material */
2659 g_pars.vec := f_gen_auth_vec_3g();
2660 autn := {
2661 elementIdentifier := '28'O,
2662 lengthIndicator := lengthof(g_pars.vec.autn),
2663 autnValue := g_pars.vec.autn
2664 };
2665
2666 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2667 g_pars.vec.sres,
2668 g_pars.vec.kc,
2669 g_pars.vec.ik,
2670 g_pars.vec.ck,
2671 g_pars.vec.autn,
2672 g_pars.vec.res));
2673 /* send new key material */
2674 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2675
2676 /* wait for the new Auth Request */
2677 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2678 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002679 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002680 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2681 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2682 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2683 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2684 valueField := substr(g_pars.vec.res, 0, 4)
2685 };
2686 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2687 elementIdentifier := '21'O,
2688 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2689 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2690 };
2691 l3_mo := valueof(auth_ciph_resp);
2692 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2693 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2694 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2695 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2696 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002697 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002698 deactivate(di);
2699
2700 /* Expect SGSN to perform LU with HLR */
2701 f_gmm_gsup_lu_isd();
2702
Harald Welte955aa942019-05-03 01:29:29 +02002703 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2704 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002705 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002706 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002707 setverdict(pass);
2708}
2709
2710testcase TC_attach_usim_resync() runs on test_CT {
2711 /* MS -> SGSN: Attach Request
2712 * MS <- SGSN: Identity Request IMSI
2713 * MS -> SGSN: Identity Response IMSI
2714 * MS <- SGSN: Identity Request IMEI
2715 * MS -> SGSN: Identity Response IMEI
2716 * HLR<- SGSN: SAI Request
2717 * HLR-> SGSN: SAI Response
2718 * MS <- SGSN: Auth Request
2719 * MS -> SGSN: Auth Failure (with AUTS)
2720 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2721 * HLR-> SGSN: SAI Response (new key material)
2722 * MS <- SGSN: Auth Request (new key material)
2723 * MS -> SGSN: Auth Response
2724 * MS <- SGSN: Attach Accept
2725 * MS -> SGSN: Attach Complete
2726 */
2727 var BSSGP_ConnHdlr vc_conn;
2728 f_init();
2729 f_sleep(1.0);
2730 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2731 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002732 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002733}
2734
Harald Weltea05b8072019-04-23 22:35:05 +02002735
2736/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2737private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2738 f_gmm_attach(false, false);
2739 f_sleep(1.0);
2740 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2741 /* try to detach to check if SGSN is still alive */
2742 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2743}
2744testcase TC_llc_null() runs on test_CT {
2745 var BSSGP_ConnHdlr vc_conn;
2746 f_init();
2747 f_sleep(1.0);
2748 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2749 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002750 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002751}
2752
Harald Welte645a1512019-04-23 23:18:23 +02002753/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2754private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2755 f_gmm_attach(false, false);
2756 f_sleep(1.0);
2757 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002758 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002759 setverdict(pass);
2760}
2761testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2762 var BSSGP_ConnHdlr vc_conn;
2763 f_init();
2764 f_sleep(1.0);
2765 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2766 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002767 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002768}
2769
2770/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2771private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2772 f_gmm_attach(false, false);
2773 f_sleep(1.0);
2774 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002775 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002776 setverdict(pass);
2777}
2778testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2779 var BSSGP_ConnHdlr vc_conn;
2780 f_init();
2781 f_sleep(1.0);
2782 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2783 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002784 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002785}
2786
Harald Welte2aaac1b2019-05-02 10:02:53 +02002787/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2788private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2789 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2790 var template (value) XID_Information xid;
2791 var template XID_Information xid_rx;
2792
2793 /* first perform regular attach */
2794 f_TC_attach(id);
2795 /* then activate PDP context */
2796 f_pdp_ctx_act(apars);
2797
2798 /* start MO XID */
2799 xid := { ts_XID_L3(''O) };
2800 xid_rx := { tr_XID_L3(''O) };
2801 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2802 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002803 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002804 [] as_xid(apars);
2805 }
2806 setverdict(pass);
2807}
2808testcase TC_xid_empty_l3() runs on test_CT {
2809 var BSSGP_ConnHdlr vc_conn;
2810 f_init();
2811 f_sleep(1.0);
2812 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2813 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002814 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002815}
2816
2817private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2818 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2819 var template (value) XID_Information xid;
2820 var template XID_Information xid_rx;
2821
2822 /* first perform regular attach */
2823 f_TC_attach(id);
2824 /* then activate PDP context */
2825 f_pdp_ctx_act(apars);
2826
2827 /* start MO XID */
2828 xid := { ts_XID_N201U(1234) };
2829 xid_rx := { tr_XID_N201U(1234) };
2830 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2831 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002832 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002833 [] as_xid(apars);
2834 }
2835 setverdict(pass);
2836}
2837testcase TC_xid_n201u() runs on test_CT {
2838 var BSSGP_ConnHdlr vc_conn;
2839 f_init();
2840 f_sleep(1.0);
2841 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2842 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002843 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002844}
2845
Alexander Couzens6bee0872019-05-11 01:48:50 +02002846private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2847 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2848
2849 /* first perform regular attach */
2850 f_TC_attach(id);
2851 /* then activate PDP context */
2852 f_pdp_ctx_act(apars);
2853 /* do a normal detach */
2854 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2855}
2856
2857testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2858 /* MS -> SGSN: Attach Request
2859 * MS <-> SGSN: [..]
2860 * MS -> SGSN: Attach Complete
2861 * MS -> SGSN: PDP Activate Request
2862 * MS <- SGSN: PDP Activate Accept
2863 * MS -> SGSN: GMM Detach Request
2864 * MS <- SGSN: GMM Detach Accept
2865 */
2866 var BSSGP_ConnHdlr vc_conn;
2867 f_init();
2868 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2869 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002870 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002871}
Harald Welte645a1512019-04-23 23:18:23 +02002872
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002873private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2874 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2875 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2876 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2877 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2878 var PDU_L3_SGSN_MS l3_mt;
2879
2880 f_send_l3(attach_req, 0);
2881
2882 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2883
2884 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2885 alt {
2886 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2887 setverdict(pass);
2888 }
2889 [] BSSGP[0].receive { repeat; }
2890 }
2891}
2892
2893/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2894 * See OS#3957 and OS#4245 for more information.
2895 */
2896testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2897 /*
2898 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2899 * MS <-- SGSN: Identity Request (IMEI)
2900 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2901 */
2902 var BSSGP_ConnHdlr vc_conn;
2903 f_init();
2904 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2905 vc_conn.done;
2906 f_cleanup();
2907}
2908
Harald Welte8e5932e2020-06-17 22:12:54 +02002909private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2910var PDU_BSSGP rx;
2911[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2912 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2913 mtc.stop;
2914 }
2915}
2916
2917/* SUSPEND, then DL traffic: should not pass + no paging expected */
2918private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2919 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2920 var default d;
2921
2922 /* first perform regular attach */
2923 f_TC_attach(id);
2924 /* then activate PDP context */
2925 f_pdp_ctx_act(apars);
2926 /* then transceive a downlink PDU */
2927 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2928
2929 /* now suspend GPRS */
2930 f_bssgp_suspend();
2931
2932 d := activate(as_nopaging_ps());
2933
2934 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2935 * nor any related paging requests */
2936 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2937
2938 deactivate(d);
2939}
2940testcase TC_suspend_nopaging() runs on test_CT {
2941 var BSSGP_ConnHdlr vc_conn;
2942 f_init();
2943 f_sleep(1.0);
2944 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
2945 vc_conn.done;
2946 f_cleanup();
2947}
2948
2949
2950/* SUSPEND, then RESUME: data expected to flow after explicit resume */
2951private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
2952 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2953 var OCT1 susp_ref;
2954 var default d;
2955
2956 /* first perform regular attach */
2957 f_TC_attach(id);
2958 /* then activate PDP context */
2959 f_pdp_ctx_act(apars);
2960 /* then transceive a downlink PDU */
2961 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2962
2963 /* now suspend GPRS */
2964 susp_ref := f_bssgp_suspend();
2965
2966 d := activate(as_nopaging_ps());
2967
2968 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2969 * nor any related paging requests */
2970 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2971
2972 deactivate(d);
2973
2974 /* resume GPRS */
2975 f_bssgp_resume(susp_ref);
2976
2977 /* now data should be flowing again */
2978 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2979}
2980testcase TC_suspend_resume() runs on test_CT {
2981 var BSSGP_ConnHdlr vc_conn;
2982 f_init();
2983 f_sleep(1.0);
2984 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
2985 vc_conn.done;
2986 f_cleanup();
2987}
2988
2989/* SUSPEND, then RAU: data expected to flow after implicit resume */
2990private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
2991 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2992 var default d;
2993
2994 /* first perform regular attach */
2995 f_TC_attach(id);
2996 /* then activate PDP context */
2997 f_pdp_ctx_act(apars);
2998 /* then transceive a downlink PDU */
2999 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3000
3001 /* now suspend GPRS */
3002 f_bssgp_suspend();
3003
3004 d := activate(as_nopaging_ps());
3005
3006 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3007 * nor any related paging requests */
3008 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3009
3010 deactivate(d);
3011
3012 /* perform RAU (implicit RESUME) */
3013 f_routing_area_update(g_pars.ra);
3014
3015 /* now data should be flowing again */
3016 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3017
3018}
3019testcase TC_suspend_rau() runs on test_CT {
3020 var BSSGP_ConnHdlr vc_conn;
3021 f_init();
3022 f_sleep(1.0);
3023 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3024 vc_conn.done;
3025 f_cleanup();
3026}
3027
3028
3029/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3030private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3031 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3032 var default d;
3033
3034 /* first perform regular attach */
3035 f_TC_attach(id);
3036 /* then activate PDP context */
3037 f_pdp_ctx_act(apars);
3038 /* then transceive a downlink PDU */
3039 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3040
3041 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3042 f_sleep(5.0);
3043
3044 /* now data should be flowing again, but with PS PAGING */
3045 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3046 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3047
3048 /* FIXME: simulate paging response */
3049 /* FIXME: verify PDU actually arrives only after paging response was successful */
3050
3051}
3052testcase TC_paging_ps() runs on test_CT {
3053 var BSSGP_ConnHdlr vc_conn;
3054 f_init();
3055 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3056 f_sleep(1.0);
3057 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3058 vc_conn.done;
3059 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3060 f_cleanup();
3061}
3062
3063
3064
3065
3066
Harald Welte5ac31492018-02-15 20:39:13 +01003067control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003068 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003069 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003070 execute( TC_attach_umts_aka_umts_res() );
3071 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003072 execute( TC_attach_auth_id_timeout() );
3073 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003074 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003075 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003076 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003077 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003078 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003079 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003080 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003081 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003082 execute( TC_attach_closed_add_vty(), 20.0 );
3083 execute( TC_attach_check_subscriber_list(), 20.0 );
3084 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003085 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003086 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3087 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3088 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3089 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003090 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003091 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003092 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003093 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003094 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003095 execute( TC_detach_unknown_nopoweroff() );
3096 execute( TC_detach_unknown_poweroff() );
3097 execute( TC_detach_nopoweroff() );
3098 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003099 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003100 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003101 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003102 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003103 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003104 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003105 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003106 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003107 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003108 execute( TC_attach_restart_ctr_echo() );
3109 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003110 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003111 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3112 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003113 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003114 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003115 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003116
Harald Welte2aaac1b2019-05-02 10:02:53 +02003117 execute( TC_xid_empty_l3() );
3118 execute( TC_xid_n201u() );
3119
Harald Weltea05b8072019-04-23 22:35:05 +02003120 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003121 execute( TC_llc_sabm_dm_llgmm() );
3122 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003123
Harald Welte8e5932e2020-06-17 22:12:54 +02003124 execute( TC_suspend_nopaging() );
3125 execute( TC_suspend_resume() );
3126 execute( TC_suspend_rau() );
3127 execute( TC_paging_ps() );
3128
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003129 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3130 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003131}
Harald Welte96a33b02018-02-04 10:36:22 +01003132
3133
3134
3135}