blob: c6e22ccc626e683bdeb4d2ea0294ad9f83d7f3c1 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010074 handle_sns := false,
75 nsvc := {
76 {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 21010,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010083 remote_ip := "127.0.0.1",
84 data_weight := 1,
85 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010086 }
87 },
88 nsvci := 97
89 }
90 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020091 },
92 {
Harald Welte5e514fa2018-07-05 00:01:45 +020093 nsei := 97,
94 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010095 handle_sns := false,
96 nsvc := {
97 {
98 provider := {
99 ip := {
100 address_family := AF_INET,
101 local_udp_port := 21011,
102 local_ip := "127.0.0.1",
103 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100104 remote_ip := "127.0.0.1",
105 data_weight := 1,
106 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100107 }
108 },
109 nsvci := 98
110 }
111 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200112 },
113 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200114 nsei := 98,
115 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100116 handle_sns := false,
117 nsvc := {
118 {
119 provider := {
120 ip := {
121 address_family := AF_INET,
122 local_udp_port := 21012,
123 local_ip := "127.0.0.1",
124 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100125 remote_ip := "127.0.0.1",
126 data_weight := 1,
127 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100128 }
129 },
130 nsvci := 99
131 }
132 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200133 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200134 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200135
136 RAN_Configurations mp_ranap_cfg := {
137 {
138 transport := RANAP_TRANSPORT_IuCS,
139 sccp_service_type := "mtp3_itu",
140 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
141 own_pc := 195,
142 own_ssn := 142,
143 peer_pc := 188, /* 0.23.4 */
144 peer_ssn := 142,
145 sio := '83'O,
146 rctx := 2
147 }
148 }
Harald Welte5ac31492018-02-15 20:39:13 +0100149};
150
Harald Welte5339b2e2020-10-04 22:52:56 +0200151const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100152type record GbInstance {
153 NS_CT vc_NS,
154 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200155 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100156 BssgpConfig cfg
157};
Harald Welte96a33b02018-02-04 10:36:22 +0100158
Harald Welte2fa771f2019-05-02 20:13:53 +0200159const integer NUM_GB := 3;
160type record length(NUM_GB) of GbInstance GbInstances;
161type record length(NUM_GB) of NSConfiguration NSConfigurations;
162type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200163
Harald Welte26fbb6e2019-04-14 17:32:46 +0200164const integer NUM_RNC := 1;
165type record of RAN_Configuration RAN_Configurations;
166
Harald Welte96a33b02018-02-04 10:36:22 +0100167type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200168 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200169 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200170 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100171
Harald Welte5ac31492018-02-15 20:39:13 +0100172 var GSUP_Emulation_CT vc_GSUP;
173 var IPA_Emulation_CT vc_GSUP_IPA;
174 /* only to get events from IPA underneath GSUP */
175 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100176
Harald Welte5339b2e2020-10-04 22:52:56 +0200177 /* only needed at start to get the per-BVC references */
178 port BSSGP_CT_PROC_PT PROC;
179
Philipp Maier7df55e02020-12-14 23:46:04 +0100180 /* used by RIM related test */
181 port BSSGP_PT RIM[NUM_GB];
182
Harald Welteeded9ad2018-02-17 20:57:34 +0100183 var GTP_Emulation_CT vc_GTP;
184
Harald Weltebd194722018-02-16 22:11:08 +0100185 port TELNETasp_PT SGSNVTY;
186
Harald Welte96a33b02018-02-04 10:36:22 +0100187 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200188 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100189};
190
Harald Welte26fbb6e2019-04-14 17:32:46 +0200191type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100192 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100193 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200194 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100195}
196
197type record SGSN_ConnHdlrNetworkPars {
198 boolean expect_ptmsi,
199 boolean expect_auth,
200 boolean expect_ciph
201};
202
203type record BSSGP_ConnHdlrPars {
204 /* IMEI of the simulated ME */
205 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200206 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100207 hexstring imsi,
208 /* MSISDN of the simulated MS (probably unused) */
209 hexstring msisdn,
210 /* P-TMSI allocated to the simulated MS */
211 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100212 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100213 /* TLLI of the simulated MS */
214 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100215 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100216 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200217 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200218 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
219 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100220 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100221 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200222 float t_guard,
223 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200224 SCCP_PAR_Address sccp_addr_local optional,
225 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100226};
227
Alexander Couzens89508702018-07-31 04:16:10 +0200228private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200229 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200230 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
231
232 var RoutingAreaIdentificationV ret := {
233 mccDigit1 := mcc_mnc[0],
234 mccDigit2 := mcc_mnc[1],
235 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200236 mncDigit3 := mcc_mnc[3],
237 mncDigit1 := mcc_mnc[4],
238 mncDigit2 := mcc_mnc[5],
Pau Espin Pedroldeaaa902021-02-12 18:41:04 +0100239 lac := int2oct(cell_id.ra_id.lai.lac, 2),
240 rac := int2oct(cell_id.ra_id.rac, 1)
Alexander Couzens89508702018-07-31 04:16:10 +0200241 }
242 return ret;
243};
244
Alexander Couzens51114d12018-07-31 18:41:56 +0200245private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
246 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
247 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100248 /* connect lower end of BSSGP emulation with NS upper port */
249 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100250
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200251 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200252 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
253 /* resolve the per-BVC component references */
254 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
255 connect(self:PROC, gb.vc_BSSGP:PROC);
256 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
257 disconnect(self:PROC, gb.vc_BSSGP:PROC);
258 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100259 /* connect RIM related port */
260 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100261}
262
263private function f_init_gsup(charstring id) runs on test_CT {
264 id := id & "-GSUP";
265 var GsupOps ops := {
266 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
267 };
268
269 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
270 vc_GSUP := GSUP_Emulation_CT.create(id);
271
272 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
273 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
274 /* we use this hack to get events like ASP_IPA_EVENT_UP */
275 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
276
277 vc_GSUP.start(GSUP_Emulation.main(ops, id));
278 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
279
280 /* wait for incoming connection to GSUP port before proceeding */
281 timer T := 10.0;
282 T.start;
283 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700284 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100285 [] T.timeout {
286 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200287 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100288 }
289 }
290}
291
Harald Welteeded9ad2018-02-17 20:57:34 +0100292private function f_init_gtp(charstring id) runs on test_CT {
293 id := id & "-GTP";
294
295 var GtpEmulationCfg gtp_cfg := {
296 gtpc_bind_ip := mp_ggsn_ip,
297 gtpc_bind_port := GTP1C_PORT,
298 gtpu_bind_ip := mp_ggsn_ip,
299 gtpu_bind_port := GTP1U_PORT,
300 sgsn_role := false
301 };
302
303 vc_GTP := GTP_Emulation_CT.create(id);
304 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
305}
306
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200307friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100308 map(self:SGSNVTY, system:SGSNVTY);
309 f_vty_set_prompts(SGSNVTY);
310 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200311 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100312 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
313}
314
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200315private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
316 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200317 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200318 } else {
319 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
320 }
321}
322
Harald Weltebd194722018-02-16 22:11:08 +0100323
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200324/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
325function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200326 var integer i;
327
Harald Welte96a33b02018-02-04 10:36:22 +0100328 if (g_initialized == true) {
329 return;
330 }
331 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100332 g_gb[0].cfg := {
333 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200334 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200335 bvc := {
336 {
337 bvci := 196,
338 cell_id := {
339 ra_id := {
340 lai := {
341 mcc_mnc := mcc_mnc,
342 lac := 13135
343 },
344 rac := 0
345 },
346 cell_id := 20960
347 },
Harald Welte4d112c92020-11-12 19:48:31 +0100348 depth := BSSGP_DECODE_DEPTH_L3,
349 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200350 }
351 }
Harald Welte5ac31492018-02-15 20:39:13 +0100352 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200353 g_gb[1].cfg := {
354 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200355 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200356 bvc := {
357 {
358 bvci := 210,
359 cell_id := {
360 ra_id := {
361 lai := {
362 mcc_mnc := mcc_mnc,
363 lac := 13200
364 },
365 rac := 0
366 },
367 cell_id := 20961
368 },
Harald Welte4d112c92020-11-12 19:48:31 +0100369 depth := BSSGP_DECODE_DEPTH_L3,
370 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200371 }
372 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200373 };
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100374 g_gb[2].cfg := { /* [2] configured to have same RAC as [1] */
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200375 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200376 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200377 bvc := {
378 {
379 bvci := 220,
380 cell_id := {
381 ra_id := {
382 lai := {
383 mcc_mnc := mcc_mnc,
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100384 lac := 13200
Harald Welte5339b2e2020-10-04 22:52:56 +0200385 },
386 rac := 0
387 },
388 cell_id := 20962
389 },
Harald Welte4d112c92020-11-12 19:48:31 +0100390 depth := BSSGP_DECODE_DEPTH_L3,
391 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200392 }
393 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200394 };
Harald Welte96a33b02018-02-04 10:36:22 +0100395
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200396 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200397 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
398 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
399 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200400
Alexander Couzens1552e792019-07-23 20:38:39 +0200401 if (g_ranap_enable) {
402 for (i := 0; i < NUM_RNC; i := i+1) {
403 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
404 f_ran_adapter_start(g_ranap[i]);
405 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200406 }
Harald Welte5ac31492018-02-15 20:39:13 +0100407 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100408 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200409 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100410}
Harald Welte96a33b02018-02-04 10:36:22 +0100411
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200412function f_cleanup() runs on test_CT {
413 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200414 if (g_ranap_enable) {
415 for (i := 0; i < NUM_RNC; i := i+1) {
416 f_ran_adapter_cleanup(g_ranap[i]);
417 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200418 }
419 self.stop;
420}
421
Harald Welte26fbb6e2019-04-14 17:32:46 +0200422private function RncUnitdataCallback(RANAP_PDU ranap)
423runs on RAN_Emulation_CT return template RANAP_PDU {
424 var template RANAP_PDU resp := omit;
425
426 log ("RANAP_RncUnitDataCallback");
427 /* answer all RESET with RESET ACK */
428 if (match(ranap, tr_RANAP_Reset)) {
429 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
430 var CN_DomainIndicator dom;
431 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
432 resp := ts_RANAP_ResetAck(dom);
433 }
434 return resp;
435}
436
437const RanOps RNC_RanOps := {
438 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
439 ranap_unitdata_cb := refers(RncUnitdataCallback),
440 ps_domain := true,
441 decode_dtap := true,
442 role_ms := true,
443 protocol := RAN_PROTOCOL_RANAP,
444 transport := RANAP_TRANSPORT_IuCS,
445 use_osmux := false,
446 sccp_addr_local := omit,
447 sccp_addr_peer := omit
448};
449
Harald Welte5ac31492018-02-15 20:39:13 +0100450type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
451
452/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200453function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100454 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100455runs on test_CT return BSSGP_ConnHdlr {
456 var BSSGP_ConnHdlr vc_conn;
457 var SGSN_ConnHdlrNetworkPars net_pars := {
458 expect_ptmsi := true,
459 expect_auth := true,
460 expect_ciph := false
461 };
462 var BSSGP_ConnHdlrPars pars := {
463 imei := f_gen_imei(imsi_suffix),
464 imsi := f_gen_imsi(imsi_suffix),
465 msisdn := f_gen_msisdn(imsi_suffix),
466 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100467 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100468 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100469 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100470 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200471 bssgp_cell_id := {
472 gb[0].cfg.bvc[0].cell_id,
473 gb[1].cfg.bvc[0].cell_id,
474 gb[2].cfg.bvc[0].cell_id
475 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200476 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100477 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100478 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200479 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200480 sccp_addr_local := omit,
481 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100482 };
483
Alexander Couzens1552e792019-07-23 20:38:39 +0200484 if (g_ranap_enable) {
485 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
486 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
487 }
488
Harald Welte5ac31492018-02-15 20:39:13 +0100489 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200490
491 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
492 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
493 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100494 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200495
496 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
497 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
498 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100499 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200500
501 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
502 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
503 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100504 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100505
Harald Welte26fbb6e2019-04-14 17:32:46 +0200506 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200507 if (g_ranap_enable) {
508 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
509 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
510 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200511
Harald Welte5ac31492018-02-15 20:39:13 +0100512 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
513 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
514
Harald Welteeded9ad2018-02-17 20:57:34 +0100515 connect(vc_conn:GTP, vc_GTP:CLIENT);
516 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
517
Harald Welte5ac31492018-02-15 20:39:13 +0100518 vc_conn.start(f_handler_init(fn, id, pars));
519 return vc_conn;
520}
521
Harald Welte62e29582018-02-16 21:17:11 +0100522private altstep as_Tguard() runs on BSSGP_ConnHdlr {
523 [] g_Tguard.timeout {
524 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200525 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100526 }
527}
528
Harald Welte5ac31492018-02-15 20:39:13 +0100529/* first function called in every ConnHdlr */
530private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
531runs on BSSGP_ConnHdlr {
532 /* do some common stuff like setting up g_pars */
533 g_pars := pars;
534
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200535 llc := f_llc_create(false);
536
Harald Welte5ac31492018-02-15 20:39:13 +0100537 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200538 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100539 /* tell GSUP dispatcher to send this IMSI to us */
540 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100541 /* tell GTP dispatcher to send this IMSI to us */
542 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100543
Harald Welte62e29582018-02-16 21:17:11 +0100544 g_Tguard.start(pars.t_guard);
545 activate(as_Tguard());
546
Harald Welte5ac31492018-02-15 20:39:13 +0100547 /* call the user-supplied test case function */
548 fn.apply(id);
549 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100550}
551
552/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100553 * Detach without Attach
554 * SM procedures without attach / RAU
555 * ATTACH / RAU
556 ** with / without authentication
557 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100558 * re-transmissions of LLC frames
559 * PDP Context activation
560 ** with different GGSN config in SGSN VTY
561 ** with different PDP context type (v4/v6/v46)
562 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100563 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100564 */
565
566testcase TC_wait_ns_up() runs on test_CT {
567 f_init();
568 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200569 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100570}
571
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572friend function is_gb(integer ran_index) return boolean {
573 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200574}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200575friend function is_iu(integer ran_index) return boolean {
576 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200577}
578
Alexander Couzens0507ec32019-09-15 22:41:22 +0200579function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200580 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200581 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 +0200582}
583
Alexander Couzens0507ec32019-09-15 22:41:22 +0200584private 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 +0200585 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
586 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
587 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200588 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200589}
590
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200591/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
592function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
593 log("Sending InitialUE: ", l3_mo);
594 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
595 var RANAP_PDU ranap;
596 var LAI lai := {
597 pLMNidentity := '62F224'O,
598 lAC := '1234'O,
599 iE_Extensions := omit
600 };
601 var SAI sai := {
602 pLMNidentity := lai.pLMNidentity,
603 lAC := lai.lAC,
604 sAC := '0000'O, /* FIXME */
605 iE_Extensions := omit
606 };
607 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
608 var GlobalRNC_ID grnc_id := {
609 pLMNidentity := lai.pLMNidentity,
610 rNC_ID := 2342 /* FIXME */
611 };
612
613 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
614 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
615 alt {
616 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
617 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
618 setverdict(fail, "DISC.ind from SCCP");
619 mtc.stop;
620 }
621 }
622}
623
624/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200625function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
626 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200627 if (g_pars.rnc_send_initial_ue) {
628 g_pars.rnc_send_initial_ue := false;
629 f_send_l3_initial_ue(l3_mo);
630 } else {
631 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
632 }
633 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200634 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200635 }
636}
637
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200638altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700639 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200640 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100641 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200642 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100643 repeat;
644 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200645 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200646 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200647 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200648 repeat;
649 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200650 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100651 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200652 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200653 repeat;
654 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200655 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200656 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200657 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100658 repeat;
659 }
660}
Harald Welte96a33b02018-02-04 10:36:22 +0100661
Harald Welteca362462019-05-02 20:11:21 +0200662/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200663function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200664runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200665 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200666 var PDU_L3_SGSN_MS l3_mt;
667 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200668 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
669 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200670 l3_mt := mt.dtap;
671 }
Harald Welteca362462019-05-02 20:11:21 +0200672 }
673 return l3_mt;
674}
675
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200676/* perform GMM authentication (if expected).
677 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
678 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200679function 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 +0100680 var PDU_L3_MS_SGSN l3_mo;
681 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200682 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100683 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200684 var GSUP_IE auth_tuple;
685 var template AuthenticationParameterAUTNTLV autn;
686
687 if (umts_aka_challenge) {
688 g_pars.vec := f_gen_auth_vec_3g();
689 autn := {
690 elementIdentifier := '28'O,
691 lengthIndicator := lengthof(g_pars.vec.autn),
692 autnValue := g_pars.vec.autn
693 };
694
695 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
696 g_pars.vec.sres,
697 g_pars.vec.kc,
698 g_pars.vec.ik,
699 g_pars.vec.ck,
700 g_pars.vec.autn,
701 g_pars.vec.res));
702 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
703 } else {
704 g_pars.vec := f_gen_auth_vec_2g();
705 autn := omit;
706 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
707 g_pars.vec.sres,
708 g_pars.vec.kc));
709 log("GSUP sends only 2G auth tuple", auth_tuple);
710 }
Harald Welteca362462019-05-02 20:11:21 +0200711
Harald Welte5ac31492018-02-15 20:39:13 +0100712 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
713 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200714
715 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
716 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200717 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100718 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200719 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
720
721 if (umts_aka_challenge and not force_gsm_sres) {
722 /* set UMTS response instead */
723 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
724 valueField := substr(g_pars.vec.res, 0, 4)
725 };
726 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
727 elementIdentifier := '21'O,
728 lengthIndicator := lengthof(g_pars.vec.res) - 4,
729 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
730 };
731 }
732
733 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100734 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
735 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
736 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
737 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
738 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200739 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200740
741 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200742 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200743 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
744 key_sts := ?)) {
745 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
746 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200747 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200748 }
749 }
Harald Welte76dee092018-02-16 22:12:59 +0100750 } else {
751 /* wait for identity procedure */
752 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100753 }
Harald Welte76dee092018-02-16 22:12:59 +0100754
Harald Welte5ac31492018-02-15 20:39:13 +0100755 deactivate(di);
756}
757
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200758function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100759 g_pars.p_tmsi := p_tmsi;
760 /* update TLLI */
761 g_pars.tlli_old := g_pars.tlli;
762 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100763 if (is_gb(ran_index)) {
764 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
765 }
Harald Weltef70997d2018-02-17 10:11:19 +0100766}
767
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100768function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100769 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100770 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100771 if (not (g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100772 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100773 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200774 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100775 }
Harald Welte04683d02018-02-16 22:43:45 +0100776 g_pars.ra := aa.routingAreaIdentification;
777 if (ispresent(aa.allocatedPTMSI)) {
778 if (not g_pars.net.expect_ptmsi) {
779 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200780 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100781 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100782 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
783 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100784 }
785 if (ispresent(aa.msIdentity)) {
786 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200787 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100788 }
789 /* P-TMSI.sig */
790 if (ispresent(aa.ptmsiSignature)) {
791 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
792 }
793 /* updateTimer */
794 // aa.readyTimer
795 /* T3302, T3319, T3323, T3312_ext, T3324 */
796}
797
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200798function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100799 /* mandatory IE */
800 g_pars.ra := ra.routingAreaId;
801 if (ispresent(ra.allocatedPTMSI)) {
802 if (not g_pars.net.expect_ptmsi) {
803 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200804 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100805 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100806 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
807 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100808 }
809 if (ispresent(ra.msIdentity)) {
810 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200811 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100812 }
813 /* P-TMSI.sig */
814 if (ispresent(ra.ptmsiSignature)) {
815 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
816 }
817 /* updateTimer */
818 // aa.readyTimer
819 /* T3302, T3319, T3323, T3312_ext, T3324 */
820}
821
822
Harald Welte5a4fa042018-02-16 20:59:21 +0100823function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
824 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
825}
826
Harald Welte23178c52018-02-17 09:36:33 +0100827/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700828private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100829 if (ispresent(g_pars.p_tmsi)) {
830 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
831 } else {
832 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
833 }
834}
835
Harald Welte311ec272018-02-17 09:40:03 +0100836private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100837 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100838 /* Expect MSC to perform LU with HLR */
839 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100840 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
841 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
842 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100843 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
844 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
845}
846
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100847friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
848 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
849 var RoutingAreaIdentificationV old_ra_val;
850 var template PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200851 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100852
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100853 if (istemplatekind(old_ra, "omit")) {
854 old_ra_val := f_random_RAI();
855 } else {
856 old_ra_val := valueof(old_ra);
857 }
858
859 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200860 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
861 * 3G auth vectors */
862 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
863 /* The thing is, if the solSACapability is 'omit', then the
864 * revisionLevelIndicatior is at the wrong place! */
865 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
866
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200867 f_send_l3(attach_req, ran_index);
868 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200869 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100870 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100871
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200872 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100873 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200874
Harald Welte04683d02018-02-16 22:43:45 +0100875 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200876 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200877
878 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200879 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200880 as_iu_release_compl_disc();
881 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200882
883 /* Race condition
884 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
885 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
886 * arrived before it. This results in a test case failure.
887 * Delay execution by 50 ms
888 */
889 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200890}
891
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200892friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
893 timer T := 5.0;
894 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100895 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200896 T.start;
897 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100898 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200899 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
900 }
Harald Welte9b461a92020-12-10 23:41:14 +0100901 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200902 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
903 mtc.stop;
904 }
905 [] T.timeout {
906 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
907 mtc.stop;
908 }
909 }
910 return '00'O;
911}
912
913friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
914 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100915 BSSGP_GLOBAL[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200916 T.start;
917 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100918 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
919 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200920?)) {
921 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
922 mtc.stop;
923 }
924 [] T.timeout {
925 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
926 mtc.stop;
927 }
928 }
929}
930
931
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200932private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
933 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100934 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100935}
936
937testcase TC_attach() runs on test_CT {
938 var BSSGP_ConnHdlr vc_conn;
939 f_init();
940 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200941 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100942 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200943 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100944}
945
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100946testcase TC_attach_mnc3() runs on test_CT {
947 var BSSGP_ConnHdlr vc_conn;
948 f_init('023042'H);
949 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200950 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100951 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200952 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100953}
954
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200955private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
956 f_gmm_attach(true, false);
957 setverdict(pass);
958}
959testcase TC_attach_umts_aka_umts_res() runs on test_CT {
960 var BSSGP_ConnHdlr vc_conn;
961 f_init();
962 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200963 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200964 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200965 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200966}
967
968private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
969 f_gmm_attach(true, true);
970 setverdict(pass);
971}
972testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
973 var BSSGP_ConnHdlr vc_conn;
974 f_init();
975 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200976 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200977 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200978 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200979}
980
Harald Welte5b7c8122018-02-16 21:48:17 +0100981/* MS never responds to ID REQ, expect ATTACH REJECT */
982private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100983 var RoutingAreaIdentificationV old_ra := f_random_RAI();
984
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200985 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100986 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200987 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100988 /* don't send ID Response */
989 repeat;
990 }
Harald Welte955aa942019-05-03 01:29:29 +0200991 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100992 setverdict(pass);
993 }
Harald Welte955aa942019-05-03 01:29:29 +0200994 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100995 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200996 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100997 }
998 }
999}
1000testcase TC_attach_auth_id_timeout() runs on test_CT {
1001 var BSSGP_ConnHdlr vc_conn;
1002 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001003 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 +01001004 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001005 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001006}
1007
1008/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1009private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001010 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1011
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001012 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001013 alt {
1014 [] as_mm_identity();
1015 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1016 }
1017 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001018 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001019 setverdict(pass);
1020}
1021testcase TC_attach_auth_sai_timeout() runs on test_CT {
1022 var BSSGP_ConnHdlr vc_conn;
1023 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001024 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001025 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001026 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001027}
1028
Harald Weltefe253882018-02-17 09:25:00 +01001029/* HLR rejects SAI, expect ATTACH REJECT */
1030private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001031 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1032
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001033 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001034 alt {
1035 [] as_mm_identity();
1036 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1037 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1038 }
1039 }
Harald Welte955aa942019-05-03 01:29:29 +02001040 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001041 setverdict(pass);
1042}
1043testcase TC_attach_auth_sai_reject() runs on test_CT {
1044 var BSSGP_ConnHdlr vc_conn;
1045 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001046 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001047 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001048 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001049}
1050
Harald Welte5b7c8122018-02-16 21:48:17 +01001051/* HLR never responds to UL REQ, expect ATTACH REJECT */
1052private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001053 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001054 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1055
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001056 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001057 f_gmm_auth();
1058 /* Expect MSC to perform LU with HLR */
1059 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1060 /* Never follow-up with ISD_REQ or UL_RES */
1061 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001062 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001063 setverdict(pass);
1064 }
Harald Welte955aa942019-05-03 01:29:29 +02001065 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1066 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001067 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001068 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001069 }
1070 }
1071}
1072testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1073 var BSSGP_ConnHdlr vc_conn;
1074 f_init();
1075 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001076 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001077 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001078 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001079}
1080
Harald Welteb7c14e92018-02-17 09:29:16 +01001081/* HLR rejects UL REQ, expect ATTACH REJECT */
1082private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001083 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001084 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1085
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001086 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001087 f_gmm_auth();
1088 /* Expect MSC to perform LU with HLR */
1089 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1090 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1091 }
1092 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001093 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001094 setverdict(pass);
1095 }
Harald Welte955aa942019-05-03 01:29:29 +02001096 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1097 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001098 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001099 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001100 }
1101 }
1102}
1103testcase TC_attach_gsup_lu_reject() runs on test_CT {
1104 var BSSGP_ConnHdlr vc_conn;
1105 f_init();
1106 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001107 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001108 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001109 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001110}
1111
1112
Harald Welte3823e2e2018-02-16 21:53:48 +01001113/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1114private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001115 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001116 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1117
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001118 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001119 f_gmm_auth();
1120 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001121 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001122
Harald Welte955aa942019-05-03 01:29:29 +02001123 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1124 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001125 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001126 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001127 setverdict(pass);
1128}
Harald Welte3823e2e2018-02-16 21:53:48 +01001129testcase TC_attach_combined() runs on test_CT {
1130 var BSSGP_ConnHdlr vc_conn;
1131 f_init();
1132 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001133 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001134 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001135 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001136}
1137
Harald Welte76dee092018-02-16 22:12:59 +01001138/* Attempt of GPRS ATTACH in 'accept all' mode */
1139private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001140 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001141 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1142
1143 g_pars.net.expect_auth := false;
1144
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001145 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001146 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001147 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1148 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001149 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001150 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001151 setverdict(pass);
1152}
1153testcase TC_attach_accept_all() runs on test_CT {
1154 var BSSGP_ConnHdlr vc_conn;
1155 f_init();
1156 f_sleep(1.0);
1157 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001158 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001159 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001160 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001161}
Harald Welte5b7c8122018-02-16 21:48:17 +01001162
Harald Welteb2124b22018-02-16 22:26:56 +01001163/* Attempt of GPRS ATTACH in 'accept all' mode */
1164private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001165 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1166
1167 /* Simulate a foreign IMSI */
1168 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001169 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001170
1171 g_pars.net.expect_auth := false;
1172
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001173 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001174 alt {
1175 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001176 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001177 setverdict(pass);
1178 }
Harald Welte955aa942019-05-03 01:29:29 +02001179 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001180 setverdict(pass);
1181 }
Harald Welte955aa942019-05-03 01:29:29 +02001182 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001183 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001184 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001185 }
Harald Welteb2124b22018-02-16 22:26:56 +01001186 }
1187}
1188testcase TC_attach_closed() runs on test_CT {
1189 var BSSGP_ConnHdlr vc_conn;
1190 f_init();
1191 f_sleep(1.0);
1192 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1193 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001194 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001195 vc_conn.done;
1196 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001197 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001198 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001199 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001200}
1201
Harald Welte04683d02018-02-16 22:43:45 +01001202/* Routing Area Update from Unknown TLLI -> REJECT */
1203private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001204 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1205
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001206 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 +01001207 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001208 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001209 setverdict(pass);
1210 }
1211 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001212 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001213 }
1214}
1215testcase TC_rau_unknown() runs on test_CT {
1216 var BSSGP_ConnHdlr vc_conn;
1217 f_init();
1218 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001219 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001220 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001221 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001222}
1223
Harald Welte91636de2018-02-17 10:16:14 +01001224private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001225 /* first perform regular attach */
1226 f_TC_attach(id);
1227
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001228 f_routing_area_update(g_pars.ra);
1229
Harald Welte91636de2018-02-17 10:16:14 +01001230}
1231testcase TC_attach_rau() runs on test_CT {
1232 var BSSGP_ConnHdlr vc_conn;
1233 f_init();
1234 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001235 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001236 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001237 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001238}
Harald Welte04683d02018-02-16 22:43:45 +01001239
Harald Welte6abb9fe2018-02-17 15:24:48 +01001240/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001241function 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 +02001242 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001243 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001244 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001245 if (expect_purge) {
1246 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1247 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1248 }
1249 T.start;
1250 alt {
1251 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1252 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001253 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001254 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001255 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001256 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001257 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001258 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001259 /* TODO: check if any PDP contexts are deactivated on network side? */
1260 }
1261 [power_off] T.timeout {
1262 setverdict(pass);
1263 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001264 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001265 g_pars.ra := omit;
1266 setverdict(pass);
1267 /* TODO: check if any PDP contexts are deactivated on network side? */
1268 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001269 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001270 if (power_off) {
1271 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1272 } else {
1273 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1274 }
1275 mtc.stop;
1276 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001277 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001278 }
1279}
1280
1281/* IMSI DETACH (non-power-off) for unknown TLLI */
1282private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1283 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1284}
1285testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1286 var BSSGP_ConnHdlr vc_conn;
1287 f_init();
1288 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001289 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001290 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001291 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001292}
1293
1294/* IMSI DETACH (power-off) for unknown TLLI */
1295private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1296 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1297}
1298testcase TC_detach_unknown_poweroff() runs on test_CT {
1299 var BSSGP_ConnHdlr vc_conn;
1300 f_init();
1301 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001302 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001303 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001304 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001305}
1306
1307/* IMSI DETACH (non-power-off) for known TLLI */
1308private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1309 /* first perform regular attach */
1310 f_TC_attach(id);
1311
1312 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1313}
1314testcase TC_detach_nopoweroff() runs on test_CT {
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
1317 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001318 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001319 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001320 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001321}
1322
1323/* IMSI DETACH (power-off) for known TLLI */
1324private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1325 /* first perform regular attach */
1326 f_TC_attach(id);
1327
1328 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1329}
1330testcase TC_detach_poweroff() runs on test_CT {
1331 var BSSGP_ConnHdlr vc_conn;
1332 f_init();
1333 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001334 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001335 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001336 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001337}
1338
Harald Welteeded9ad2018-02-17 20:57:34 +01001339type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001340 BIT3 tid, /* L3 Transaction ID */
1341 BIT4 nsapi, /* SNDCP NSAPI */
1342 BIT4 sapi, /* LLC SAPI */
1343 QoSV qos, /* QoS parameters */
1344 PDPAddressV addr, /* IP address */
1345 octetstring apn optional, /* APN name */
1346 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1347 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001348 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001349 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001350
Harald Welte822f9102018-02-18 20:39:06 +01001351 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1352 OCT4 ggsn_tei_u, /* GGSN TEI User */
1353 octetstring ggsn_ip_c, /* GGSN IP Control */
1354 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001355 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001356
Harald Welte822f9102018-02-18 20:39:06 +01001357 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1358 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1359 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1360 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001361};
1362
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001363
1364private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1365 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1366 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1367 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1368 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1369 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1370 f_gtp_register_teid(apars.ggsn_tei_c);
1371 f_gtp_register_teid(apars.ggsn_tei_u);
1372}
1373
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001374function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001375runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001376 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1377 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001378 var template Recovery_gtpc recovery := omit;
1379
1380 if (send_recovery) {
1381 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1382 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001383
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001384 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 +02001385 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001386 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1387 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1388 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1389 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1390 apars.sgsn_tei_c, apars.gtp_resp_cause,
1391 apars.ggsn_tei_c, apars.ggsn_tei_u,
1392 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001393 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1394 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001395 }
1396 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001397 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001398 setverdict(pass);
1399 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001400 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001401 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001402 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001403 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001404 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001405 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001406 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001407 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001408 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001409 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1410 mtc.stop;
1411 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001412 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001413 setverdict(pass);
1414 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001415 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001416 }
1417}
1418
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001419function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001420runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001421 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1422 var Gtp1cUnitdata g_ud;
1423
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001424 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001425 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1426 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001427 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001428 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1429 }
1430 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001431 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001432 setverdict(pass);
1433 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001434 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001435 }
1436}
1437
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001438function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001439runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001440 var Gtp1cUnitdata g_ud;
1441 var integer seq_nr := 23;
1442 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1443
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001444 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001445 if (error_ind) {
1446 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1447 } else {
1448 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1449 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001450
1451 timer T := 5.0;
1452 T.start;
1453
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001454 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001455 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1456 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001457 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001458 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1459 repeat;
1460 }
1461 [] T.timeout {
1462 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1463 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001464 }
1465}
1466
Harald Welte6f203162018-02-18 22:04:55 +01001467
Harald Welteeded9ad2018-02-17 20:57:34 +01001468/* Table 10.5.156/3GPP TS 24.008 */
1469template (value) QoSV t_QosDefault := {
1470 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1471 delayClass := '100'B, /* best effort */
1472 spare1 := '00'B,
1473 precedenceClass := '010'B, /* normal */
1474 spare2 := '0'B,
1475 peakThroughput := '0000'B, /* subscribed */
1476 meanThroughput := '00000'B, /* subscribed */
1477 spare3 := '000'B,
1478 deliverErroneusSDU := omit,
1479 deliveryOrder := omit,
1480 trafficClass := omit,
1481 maxSDUSize := omit,
1482 maxBitrateUplink := omit,
1483 maxBitrateDownlink := omit,
1484 sduErrorRatio := omit,
1485 residualBER := omit,
1486 trafficHandlingPriority := omit,
1487 transferDelay := omit,
1488 guaranteedBitRateUplink := omit,
1489 guaranteedBitRateDownlink := omit,
1490 sourceStatisticsDescriptor := omit,
1491 signallingIndication := omit,
1492 spare4 := omit,
1493 maxBitrateDownlinkExt := omit,
1494 guaranteedBitRateDownlinkExt := omit,
1495 maxBitrateUplinkExt := omit,
1496 guaranteedBitRateUplinkExt := omit,
1497 maxBitrateDownlinkExt2 := omit,
1498 guaranteedBitRateDownlinkExt2 := omit,
1499 maxBitrateUplinkExt2 := omit,
1500 guaranteedBitRateUplinkExt2 := omit
1501}
1502
1503/* 10.5.6.4 / 3GPP TS 24.008 */
1504template (value) PDPAddressV t_AddrIPv4dyn := {
1505 pdpTypeOrg := '0001'B, /* IETF */
1506 spare := '0000'B,
1507 pdpTypeNum := '21'O, /* IPv4 */
1508 addressInfo := omit
1509}
1510template (value) PDPAddressV t_AddrIPv6dyn := {
1511 pdpTypeOrg := '0001'B, /* IETF */
1512 spare := '0000'B,
1513 pdpTypeNum := '53'O, /* IPv6 */
1514 addressInfo := omit
1515}
1516
Harald Welte37692d82018-02-18 15:21:34 +01001517template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001518 tid := '000'B,
1519 nsapi := '0101'B, /* < 5 are reserved */
1520 sapi := '0011'B, /* 3/5/9/11 */
1521 qos := t_QosDefault,
1522 addr := t_AddrIPv4dyn,
1523 apn := omit,
1524 pco := omit,
1525 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001526 gtp_resp_cause := int2oct(128, 1),
1527 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001528
1529 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001530 ggsn_tei_c := f_rnd_octstring(4),
1531 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001532 ggsn_ip_c := f_inet_addr(ggsn_ip),
1533 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001534 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001535
Harald Welteeded9ad2018-02-17 20:57:34 +01001536 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001537 sgsn_tei_u := omit,
1538 sgsn_ip_c := omit,
1539 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001540}
1541
Harald Welte37692d82018-02-18 15:21:34 +01001542template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1543 connId := 1,
1544 remName := f_inet_ntoa(ip),
1545 remPort := GTP1U_PORT
1546}
1547
1548template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1549 connId := 1,
1550 remName := f_inet_ntoa(ip),
1551 remPort := GTP1C_PORT
1552}
1553
1554private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1555 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1556 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1557}
1558
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001559private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1560 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001561 repeat;
1562 }
1563}
1564
1565template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1566 pDU_SN_UNITDATA := {
1567 nsapi := nsapi,
1568 moreBit := ?,
1569 snPduType := '1'B,
1570 firstSegmentIndicator := ?,
1571 spareBit := ?,
1572 pcomp := ?,
1573 dcomp := ?,
1574 npduNumber := ?,
1575 segmentNumber := ?,
1576 npduNumberContinued := ?,
1577 dataSegmentSnUnitdataPdu := payload
1578 }
1579}
1580
1581/* simple case: single segment, no compression */
1582template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1583 pDU_SN_UNITDATA := {
1584 nsapi := nsapi,
1585 moreBit := '0'B,
1586 snPduType := '1'B,
1587 firstSegmentIndicator := '1'B,
1588 spareBit := '0'B,
1589 pcomp := '0000'B,
1590 dcomp := '0000'B,
1591 npduNumber := '0000'B,
1592 segmentNumber := '0000'B,
1593 npduNumberContinued := '00'O,
1594 dataSegmentSnUnitdataPdu := payload
1595 }
1596}
1597
1598/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001599private 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 +02001600runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001601 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001602 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1603 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001604 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001605 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1606 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001607 [] as_xid(apars, ran_index);
1608 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001609 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1610 [expect_fwd] T.timeout {
1611 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1612 mtc.stop;
1613 }
1614 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1615 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1616 mtc.stop;
1617 }
1618 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001619 }
1620}
1621
Harald Welte64d6b512020-06-17 16:42:00 +02001622/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001623private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0, uint9_t n_u := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001624runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001625 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1626 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1627 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001628 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001629 /* Expect PDU via GTP from SGSN on simulated GGSN */
1630 alt {
1631 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1632 }
1633}
1634
Harald Welteeded9ad2018-02-17 20:57:34 +01001635private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001636 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001637
1638 /* first perform regular attach */
1639 f_TC_attach(id);
1640
1641 f_pdp_ctx_act(apars);
1642}
1643testcase TC_attach_pdp_act() 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), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001647 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001648 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001649}
Harald Welteb2124b22018-02-16 22:26:56 +01001650
Harald Welte835b15f2018-02-18 14:39:11 +01001651/* PDP Context activation for not-attached subscriber; expect fail */
1652private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001653 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001654 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 +01001655 apars.apn, apars.pco));
1656 alt {
1657 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001658 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001659 setverdict(pass);
1660 }
1661 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1662 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001663 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001664 }
Harald Welte955aa942019-05-03 01:29:29 +02001665 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001666 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001667 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001668 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001669 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001670 }
1671}
1672testcase TC_pdp_act_unattached() runs on test_CT {
1673 var BSSGP_ConnHdlr vc_conn;
1674 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001675 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001676 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001677 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001678}
1679
Harald Welte37692d82018-02-18 15:21:34 +01001680/* ATTACH + PDP CTX ACT + user plane traffic */
1681private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1682 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1683
1684 /* first perform regular attach */
1685 f_TC_attach(id);
1686 /* then activate PDP context */
1687 f_pdp_ctx_act(apars);
1688 /* then transceive a downlink PDU */
1689 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1690 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1691}
1692testcase TC_attach_pdp_act_user() runs on test_CT {
1693 var BSSGP_ConnHdlr vc_conn;
1694 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001695 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001696 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001697 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001698}
1699
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001700/* ATTACH + PDP CTX ACT; reject from GGSN */
1701private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1702 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1703
1704 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1705 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1706
1707 /* first perform regular attach */
1708 f_TC_attach(id);
1709 /* then activate PDP context */
1710 f_pdp_ctx_act(apars);
1711}
1712testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1713 var BSSGP_ConnHdlr vc_conn;
1714 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001715 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001716 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001717 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001718}
Harald Welte835b15f2018-02-18 14:39:11 +01001719
Harald Welte6f203162018-02-18 22:04:55 +01001720/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1721private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1722 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1723
1724 /* first perform regular attach */
1725 f_TC_attach(id);
1726 /* then activate PDP context */
1727 f_pdp_ctx_act(apars);
1728 /* then transceive a downlink PDU */
1729 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1730 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1731
1732 f_pdp_ctx_deact_mo(apars, '00'O);
1733}
1734testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1735 var BSSGP_ConnHdlr vc_conn;
1736 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001737 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 +01001738 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001739 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001740}
1741
Harald Welte57b9b7f2018-02-18 22:28:13 +01001742/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1743private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1744 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1745
1746 /* first perform regular attach */
1747 f_TC_attach(id);
1748 /* then activate PDP context */
1749 f_pdp_ctx_act(apars);
1750 /* then transceive a downlink PDU */
1751 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1752 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1753
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001754 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001755}
1756testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1757 var BSSGP_ConnHdlr vc_conn;
1758 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001759 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 +01001760 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001761 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001762}
1763
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001764/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1765private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1766 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1767 var Gtp1cUnitdata g_ud;
1768 var integer i;
1769 var OCT1 cause_regular_deact := '24'O;
1770
1771 /* first perform regular attach + PDP context act */
1772 f_TC_attach(id);
1773 f_pdp_ctx_act(apars);
1774
1775 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1776 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1777
1778 for (i := 0; i < 2; i := i+1) {
1779 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1780 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1781 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1782 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1783 }
1784 }
1785
1786 alt {
1787 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1788 setverdict(pass);
1789 }
1790 [] as_xid(apars, 0);
1791 }
1792
1793 /* Make sure second DeactPdpAccept is sent: */
1794 timer T := 2.0;
1795 T.start;
1796 alt {
1797 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1798 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1799 }
1800 [] T.timeout {
1801 setverdict(pass);
1802 }
1803 }
1804
1805 setverdict(pass);
1806}
1807testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1808 var BSSGP_ConnHdlr vc_conn;
1809 f_init();
1810 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1811 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001812 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001813}
1814
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001815/* ATTACH + ATTACH (2nd) */
1816private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1817 g_pars.t_guard := 5.0;
1818
1819 /* first perform regular attach */
1820 f_TC_attach(id);
1821
1822 /* second to perform regular attach */
1823 f_TC_attach(id);
1824}
1825
1826
1827testcase TC_attach_second_attempt() runs on test_CT {
1828 var BSSGP_ConnHdlr vc_conn;
1829 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001830 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001831 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001832 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001833}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001834
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001835private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1836 var Gtp1cUnitdata g_ud;
1837 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1838 var integer seq_nr;
1839
1840 /* first perform regular attach */
1841 f_TC_attach(id);
1842 /* then activate PDP context */
1843 f_pdp_ctx_act(apars);
1844
1845 /* Wait to receive first echo request and send initial Restart counter */
1846 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1847 BSSGP[0].clear;
1848 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1849 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1850 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1851 }
1852
1853 /* At some point next echo request not answered will timeout and SGSN
1854 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1855 timer T := 3.0 * 6.0 + 16.0;
1856 T.start;
1857 alt {
1858 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1859 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1860 setverdict(pass);
1861 }
1862 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1863 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1864 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1865 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1866 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1867 repeat;
1868 }
1869 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1870 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1871 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1872 repeat;
1873 }
1874 [] T.timeout {
1875 setverdict(fail, "BSSGP DeactPdpReq not received");
1876 mtc.stop;
1877 }
1878 [] as_xid(apars);
1879 }
1880 T.stop
1881
1882 setverdict(pass);
1883}
1884/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1885testcase TC_attach_echo_timeout() runs on test_CT {
1886 var BSSGP_ConnHdlr vc_conn;
1887 g_use_echo := true;
1888 f_init();
1889 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1890 vc_conn.done;
1891 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001892 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001893}
1894
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001895private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001896 var Gtp1cUnitdata g_ud;
1897 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1898
1899 /* first perform regular attach */
1900 f_TC_attach(id);
1901 /* Activate a pdp context against the GGSN */
1902 f_pdp_ctx_act(apars);
1903 /* Wait to receive first echo request and send initial Restart counter */
1904 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1905 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1906 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1907 }
1908 /* Wait to receive second echo request and send incremented Restart
1909 counter. This will fake a restarted GGSN, and pdp ctx allocated
1910 should be released by SGSN */
1911 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1912 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1913 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1914 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1915 }
1916 var OCT1 cause_network_failure := int2oct(38, 1)
1917 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001918 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001919 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001920 setverdict(pass);
1921 }
1922 [] as_xid(apars);
1923 }
1924 setverdict(pass);
1925}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001926/* ATTACH + trigger Recovery procedure through EchoResp */
1927testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001928 var BSSGP_ConnHdlr vc_conn;
1929 g_use_echo := true
1930 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001931 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 +02001932 vc_conn.done;
1933 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001934 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001935}
1936
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001937private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1938 var Gtp1cUnitdata g_ud;
1939 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1940 var integer seq_nr := 23;
1941 var GtpPeer peer;
1942 /* first perform regular attach */
1943 f_TC_attach(id);
1944
1945 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1946 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1947 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1948 f_pdp_ctx_act(apars, true);
1949
1950 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1951/* received. */
1952 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1953
1954 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1955 would be great to have an active pdp context here before triggering
1956 Recovery, and making sure the the DEACT request is sent by the SGSN.
1957 */
1958
1959 /* Activate a pdp context against the GGSN, send incremented Recovery
1960 IE. This should trigger the recovery path, but still this specific
1961 CTX activation should work. */
1962 apars.exp_rej_cause := omit; /* default value for tests */
1963 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1964 f_pdp_ctx_act(apars, true);
1965
1966 setverdict(pass);
1967}
1968/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1969testcase TC_attach_restart_ctr_create() runs on test_CT {
1970 var BSSGP_ConnHdlr vc_conn;
1971 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001972 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 +02001973 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001974 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001975}
1976
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001977/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1978private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1979 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1980 var integer seq_nr := 23;
1981 var GtpPeer peer;
1982 var integer i;
1983
1984 /* first perform regular attach */
1985 f_TC_attach(id);
1986 /* then activate PDP context */
1987 f_pdp_ctx_act(apars);
1988
Alexander Couzens0e510e62018-07-28 23:06:00 +02001989 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001990 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1991 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1992
1993 for (i := 0; i < 5; i := i+1) {
1994 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001995 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001996 [] as_xid(apars);
1997 }
1998 }
1999
2000 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2001
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002002 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002003 setverdict(pass);
2004}
2005testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2006 var BSSGP_ConnHdlr vc_conn;
2007 f_init();
2008 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002009 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 +02002010 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002011 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002012}
2013
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002014/* ATTACH + PDP CTX ACT dropped + retrans */
2015private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2016 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2017 var Gtp1cUnitdata g_ud_first, g_ud_second;
2018 /* first perform regular attach */
2019 f_TC_attach(id);
2020
2021 /* then activate PDP context on the Gb side */
2022 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2023 apars.apn, apars.pco), 0);
2024
2025 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2026 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2027 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2028 if (g_ud_first != g_ud_second) {
2029 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2030 mtc.stop;
2031 }
2032 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2033 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2034 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2035 apars.sgsn_tei_c, apars.gtp_resp_cause,
2036 apars.ggsn_tei_c, apars.ggsn_tei_u,
2037 apars.nsapi,
2038 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2039 omit, omit));
2040 }
Harald Welte955aa942019-05-03 01:29:29 +02002041 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002042
2043 /* Now the same with Deact */
2044 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2045 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2046 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2047 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2048 if (g_ud_first != g_ud_second) {
2049 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2050 mtc.stop;
2051 }
2052 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2053 BSSGP[0].clear;
2054 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2055 }
2056 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002057 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002058 setverdict(pass);
2059 }
2060 [] as_xid(apars, 0);
2061 }
2062
2063 setverdict(pass);
2064}
2065testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2066 var BSSGP_ConnHdlr vc_conn;
2067 f_init();
2068 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2069 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002070 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002071}
2072
2073/* Test that SGSN GTP response retransmit queue works fine */
2074private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2075 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2076 var integer seq_nr := 23;
2077 var Gtp1cUnitdata g_ud_first, g_ud_second;
2078 var template Gtp1cUnitdata g_delete_req;
2079 /* first perform regular attach + PDP context act */
2080 f_TC_attach(id);
2081 f_pdp_ctx_act(apars);
2082
2083 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2084 BSSGP[0].clear;
2085 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2086 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2087 GTP.send(g_delete_req);
2088 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002089 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002090 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2091 }
2092 [] as_xid(apars, 0);
2093 }
2094 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2095 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2096 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2097 mtc.stop;
2098 }
2099 };
2100
2101 /* Send duplicate DeleteCtxReq */
2102 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2103 GTP.send(g_delete_req);
2104 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2105 if (g_ud_first != g_ud_second) {
2106 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2107 mtc.stop;
2108 }
2109 }
2110
2111 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2112 * is handled differently by SGSN (expect "non-existent" cause) */
2113 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2114 GTP.send(g_delete_req);
2115 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2116 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2117 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2118 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2119 mtc.stop;
2120 }
2121 }
2122
2123 setverdict(pass);
2124}
2125testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2126 var BSSGP_ConnHdlr vc_conn;
2127 f_init();
2128 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2129 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002130 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002131}
2132
Alexander Couzens5e307b42018-05-22 18:12:20 +02002133private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2134 /* MS: perform regular attach */
2135 f_TC_attach(id);
2136
2137 /* HLR: cancel the location request */
2138 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2139 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002140
2141 /* ensure no Detach Request got received */
2142 timer T := 5.0;
2143 T.start;
2144 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002145 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002146 T.stop;
2147 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002148 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002149 }
2150 [] T.timeout {
2151 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002152 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002153 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002154 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002155 repeat;
2156 }
2157 }
2158}
2159
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002160/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2161private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2162 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2163
2164 /* first perform regular attach */
2165 f_TC_attach(id);
2166 /* then activate PDP context */
2167 f_pdp_ctx_act(apars);
2168 /* then transceive a downlink PDU */
2169 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2170
2171 /* Send Error indication as response from upload PDU and expect deact towards MS */
2172 f_pdp_ctx_deact_mt(apars, true);
2173}
2174testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2175 var BSSGP_ConnHdlr vc_conn;
2176 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002177 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 +02002178 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002179 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002180}
2181
Alexander Couzens5e307b42018-05-22 18:12:20 +02002182testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2183 /* MS <-> SGSN: GMM Attach
2184 * HLR -> SGSN: Cancel Location Request
2185 * HLR <- SGSN: Cancel Location Ack
2186 */
2187 var BSSGP_ConnHdlr vc_conn;
2188 f_init();
2189 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002190 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002191 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002192 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002193}
2194
2195
Alexander Couzensc87967a2018-05-22 16:09:54 +02002196private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2197 /* MS: perform regular attach */
2198 f_TC_attach(id);
2199
2200 /* HLR: cancel the location request */
2201 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2202 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2203 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2204
2205 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002206 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002207 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002208
2209 setverdict(pass);
2210}
2211
2212testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2213 /* MS <-> SGSN: GMM Attach
2214 * HLR -> SGSN: Cancel Location Request
2215 * HLR <- SGSN: Cancel Location Ack
2216 * MS <- SGSN: Detach Request
2217 * SGSN-> MS: Detach Complete
2218 */
2219 var BSSGP_ConnHdlr vc_conn;
2220 f_init();
2221 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002222 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002223 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002224 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002225}
2226
2227
Alexander Couzens6c47f292018-05-22 17:09:49 +02002228private function f_hlr_location_cancel_request_unknown_subscriber(
2229 charstring id,
2230 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2231
2232 /* HLR: cancel the location request */
2233 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2234
2235 /* cause 2 = IMSI_UNKNOWN */
2236 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2237
2238 setverdict(pass);
2239}
2240
2241private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002242 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002243}
2244
2245testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2246 /* HLR -> SGSN: Cancel Location Request
2247 * HLR <- SGSN: Cancel Location Error
2248 */
2249
2250 var BSSGP_ConnHdlr vc_conn;
2251 f_init();
2252 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002253 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 +02002254 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002255 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002256}
2257
2258private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002259 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002260}
2261
2262testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2263 /* HLR -> SGSN: Cancel Location Request
2264 * HLR <- SGSN: Cancel Location Error
2265 */
2266
2267 var BSSGP_ConnHdlr vc_conn;
2268 f_init();
2269 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002270 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 +02002271 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002272 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002273}
2274
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002275private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2276 f_TC_attach(id);
2277 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2278}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002279
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002280testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2281 /* MS <-> SGSN: Attach
2282 * MS -> SGSN: Detach Req (Power off)
2283 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2284 */
2285 var BSSGP_ConnHdlr vc_conn;
2286 var integer id := 33;
2287 var charstring imsi := hex2str(f_gen_imsi(id));
2288
2289 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002290 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002291 vc_conn.done;
2292
2293 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002294 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002295}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002296
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002297/* Attempt an attach, but loose the Identification Request (IMEI) */
2298private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2299 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002300 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002301
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002302 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 +02002303
2304 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002305 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002306 /* break */
2307 }
Harald Welte955aa942019-05-03 01:29:29 +02002308 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002309 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002310 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002311 repeat;
2312 }
Harald Welte955aa942019-05-03 01:29:29 +02002313 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002314 /* ignore ID REQ IMEI */
2315 count_req := count_req + 1;
2316 repeat;
2317 }
2318 }
2319 if (count_req != 5) {
2320 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002321 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002322 }
2323 setverdict(pass);
2324}
2325
2326testcase TC_attach_no_imei_response() runs on test_CT {
2327 /* MS -> SGSN: Attach Request IMSI
2328 * MS <- SGSN: Identity Request IMSI (optional)
2329 * MS -> SGSN: Identity Response IMSI (optional)
2330 * MS <- SGSN: Identity Request IMEI
2331 * MS -x SGSN: no response
2332 * MS <- SGSN: re-send: Identity Request IMEI 4x
2333 * MS <- SGSN: Attach Reject
2334 */
2335 var BSSGP_ConnHdlr vc_conn;
2336 f_init();
2337 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002338 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 +02002339 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002340 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002341}
2342
Alexander Couzens53f20562018-06-12 16:24:12 +02002343/* Attempt an attach, but loose the Identification Request (IMSI) */
2344private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2345 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002346 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002347
2348 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2349 g_pars.p_tmsi := 'c0000035'O;
2350
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002351 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 +02002352
2353 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002354 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002355 /* break */
2356 }
Harald Welte955aa942019-05-03 01:29:29 +02002357 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002358 /* ignore ID REQ IMSI */
2359 count_req := count_req + 1;
2360 repeat;
2361 }
Harald Welte955aa942019-05-03 01:29:29 +02002362 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002363 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002364 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002365 repeat;
2366 }
2367 }
2368 if (count_req != 5) {
2369 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002370 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002371 }
2372 setverdict(pass);
2373}
2374
2375testcase TC_attach_no_imsi_response() runs on test_CT {
2376 /* MS -> SGSN: Attach Request TMSI (unknown)
2377 * MS <- SGSN: Identity Request IMEI (optional)
2378 * MS -> SGSN: Identity Response IMEI (optional)
2379 * MS <- SGSN: Identity Request IMSI
2380 * MS -x SGSN: no response
2381 * MS <- SGSN: re-send: Identity Request IMSI 4x
2382 * MS <- SGSN: Attach Reject
2383 */
2384 var BSSGP_ConnHdlr vc_conn;
2385 f_init();
2386 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002387 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 +02002388 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002389 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002390}
2391
Alexander Couzenscf818962018-06-05 18:00:00 +02002392private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2393 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2394}
2395
2396testcase TC_attach_check_subscriber_list() runs on test_CT {
2397 /* MS <-> SGSN: Attach
2398 * VTY -> SGSN: Check if MS is in subscriber cache
2399 */
2400 var BSSGP_ConnHdlr vc_conn;
2401 var integer id := 34;
2402 var charstring imsi := hex2str(f_gen_imsi(id));
2403
2404 f_init();
2405 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002406 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002407 vc_conn.done;
2408
2409 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2410 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002411 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002412}
2413
Alexander Couzensf9858652018-06-07 16:14:53 +02002414private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2415 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002416 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002417
2418 /* unregister the old IMSI */
2419 f_bssgp_client_unregister(g_pars.imsi);
2420 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002421 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002422 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002423
2424 /* there is no auth */
2425 g_pars.net.expect_auth := false;
2426
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002427 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002428 f_gmm_auth();
2429 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002430 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002431 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002432 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002433 }
Harald Welte955aa942019-05-03 01:29:29 +02002434 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2435 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002436 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002437 setverdict(pass);
2438 }
2439 }
2440}
Alexander Couzens03d12242018-08-07 16:13:52 +02002441
2442private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2443
2444 f_TC_attach_closed_foreign(id);
2445 f_TC_attach_closed_imsi_added(id);
2446
2447}
2448
2449
Alexander Couzensf9858652018-06-07 16:14:53 +02002450testcase TC_attach_closed_add_vty() runs on test_CT {
2451 /* VTY-> SGSN: policy close
2452 * MS -> SGSN: Attach Request
2453 * MS <- SGSN: Identity Request IMSI
2454 * MS -> SGSN: Identity Response IMSI
2455 * MS <- SGSN: Attach Reject
2456 * VTY-> SGSN: policy imsi-acl add IMSI
2457 * MS -> SGSN: Attach Request
2458 * MS <- SGSN: Identity Request IMSI
2459 * MS -> SGSN: Identity Response IMSI
2460 * MS <- SGSN: Identity Request IMEI
2461 * MS -> SGSN: Identity Response IMEI
2462 * MS <- SGSN: Attach Accept
2463 */
2464 var BSSGP_ConnHdlr vc_conn;
2465 f_init();
2466 f_sleep(1.0);
2467 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2468 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002469 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2470 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002471 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002472 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002473 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002474 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002475}
2476
Alexander Couzens0085bd72018-06-12 19:08:44 +02002477/* Attempt an attach, but never answer a Attach Complete */
2478private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2479 var integer count_req := 0;
2480
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002481 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 +02002482 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002483 /* Expect SGSN to perform LU with HLR */
2484 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002485
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002486 timer T := 10.0;
2487 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002488 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002489 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002490 /* break */
2491 }
Harald Welte955aa942019-05-03 01:29:29 +02002492 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002493 /* ignore */
2494 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002495 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002496 repeat;
2497 }
2498 }
2499 if (count_req != 5) {
2500 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002501 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002502 }
2503 setverdict(pass);
2504}
2505
2506testcase TC_attach_check_complete_resend() runs on test_CT {
2507 /* MS -> SGSN: Attach Request IMSI
2508 * MS <- SGSN: Identity Request *
2509 * MS -> SGSN: Identity Response *
2510 * MS <- SGSN: Attach Complete 5x
2511 */
2512 var BSSGP_ConnHdlr vc_conn;
2513 f_init();
2514 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002515 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 +02002516 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002517 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002518}
2519
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002520friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002521 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002522 var PDU_DTAP_PS_MT mt;
2523 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002524
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002525 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002526 p_tmsi := g_pars.p_tmsi;
2527 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002528 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002529 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 +02002530 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002531 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2532 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2533 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002534 setverdict(pass);
2535 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002536 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2537 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2538 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002539 setverdict(pass);
2540 }
2541
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002542 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002543 setverdict(fail, "Unexpected RAU Reject");
2544 mtc.stop;
2545 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002546 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002547 setverdict(fail, "Unexpected RAU Reject");
2548 mtc.stop;
2549 }
2550
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002551 [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 +02002552 key_sts := ?)) {
2553 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2554 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002555 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002556 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002557 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002558 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2559 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002560 }
2561}
2562
Alexander Couzensbfda9212018-07-31 03:17:33 +02002563private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002564 /* first perform regular attach */
2565 f_TC_attach(id);
2566
2567 /* then send RAU */
2568 f_routing_area_update(g_pars.ra);
2569
2570 /* do another RAU */
2571 f_routing_area_update(g_pars.ra);
2572
2573 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2574}
2575
2576testcase TC_attach_rau_a_a() runs on test_CT {
2577 /* MS <-> SGSN: Successful Attach
2578 * MS -> SGSN: Routing Area Update Request
2579 * MS <- SGSN: Routing Area Update Accept
2580 * MS -> SGSN: Routing Area Update Request
2581 * MS <- SGSN: Routing Area Update Accept
2582 * MS -> SGSN: Detach (PowerOff)
2583 */
2584 var BSSGP_ConnHdlr vc_conn;
2585 f_init();
2586 f_sleep(1.0);
2587 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2588 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002589 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002590}
2591
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002592private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002593 f_TC_attach(id);
2594
2595 log("attach complete sending rau");
2596 f_routing_area_update(g_pars.ra, 0);
2597
2598 log("rau complete unregistering");
2599 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002600 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002601
2602 log("sending second RAU via different RA");
2603 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2604
2605 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2606}
2607
2608testcase TC_attach_rau_a_b() runs on test_CT {
2609 /* MS <-> SGSN: Successful Attach
2610 * MS -> SGSN: Routing Area _a_ Update Request
2611 * MS <- SGSN: Routing Area _a_ Update Accept
2612 * MS -> SGSN: Routing Area _b_ Update Request
2613 * MS <- SGSN: Routing Area _b_ Update Accept
2614 * MS -> SGSN: Detach (PowerOff)
2615 */
2616 var BSSGP_ConnHdlr vc_conn;
2617 f_init();
2618 f_sleep(1.0);
2619 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2620 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002621 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002622}
2623
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002624private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2625 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002626 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002627 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002628 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002629
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002630 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002631
2632 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002633 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002634 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2635 mtc.stop;
2636 }
Harald Welte955aa942019-05-03 01:29:29 +02002637 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002638 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002639 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002640 repeat;
2641 }
Harald Welte955aa942019-05-03 01:29:29 +02002642 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002643 /* send out a second GMM_Attach Request.
2644 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2645 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002646 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002647 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002648 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002649 }
2650 }
2651 f_sleep(1.0);
2652
2653 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2654 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002655 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002656 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002657 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002658 repeat;
2659 }
Harald Welte955aa942019-05-03 01:29:29 +02002660 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002661 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2662 mtc.stop;
2663 }
Harald Welte955aa942019-05-03 01:29:29 +02002664 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002665 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2666 mtc.stop;
2667 }
Harald Welte955aa942019-05-03 01:29:29 +02002668 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2669 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002670 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002671 setverdict(pass);
2672 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2673 }
2674 }
2675}
2676
2677testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2678 /* Testing if the SGSN ignore Attach Request with the exact same content */
2679 /* MS -> SGSN: Attach Request IMSI
2680 * MS <- SGSN: Identity Request IMSI (optional)
2681 * MS -> SGSN: Identity Response IMSI (optional)
2682 * MS <- SGSN: Identity Request IMEI
2683 * MS -> SGSN: Attach Request (2nd)
2684 * MS <- SGSN: Identity Response IMEI
2685 * MS <- SGSN: Attach Accept
2686 * MS -> SGSN: Attach Complete
2687 */
2688 var BSSGP_ConnHdlr vc_conn;
2689 f_init();
2690 f_sleep(1.0);
2691 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2692 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2693 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002694 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002695}
2696
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002697private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002698 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2699
2700 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2701
2702 /* send Attach Request */
2703 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2704 * 3G auth vectors */
2705 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2706 /* The thing is, if the solSACapability is 'omit', then the
2707 * revisionLevelIndicatior is at the wrong place! */
2708 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002709 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002710
2711 /* do the auth */
2712 var PDU_L3_MS_SGSN l3_mo;
2713 var PDU_L3_SGSN_MS l3_mt;
2714 var default di := activate(as_mm_identity());
2715
2716 var GSUP_IE auth_tuple;
2717 var template AuthenticationParameterAUTNTLV autn;
2718
2719 g_pars.vec := f_gen_auth_vec_3g();
2720 autn := {
2721 elementIdentifier := '28'O,
2722 lengthIndicator := lengthof(g_pars.vec.autn),
2723 autnValue := g_pars.vec.autn
2724 };
2725 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2726 g_pars.vec.sres,
2727 g_pars.vec.kc,
2728 g_pars.vec.ik,
2729 g_pars.vec.ck,
2730 g_pars.vec.autn,
2731 g_pars.vec.res));
2732 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2733 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2734 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2735
2736 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2737 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002738 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002739
2740 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002741 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002742
2743 /* wait for the GSUP resync request */
2744 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2745 g_pars.imsi,
2746 g_pars.vec.auts,
2747 g_pars.vec.rand));
2748
2749 /* generate new key material */
2750 g_pars.vec := f_gen_auth_vec_3g();
2751 autn := {
2752 elementIdentifier := '28'O,
2753 lengthIndicator := lengthof(g_pars.vec.autn),
2754 autnValue := g_pars.vec.autn
2755 };
2756
2757 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2758 g_pars.vec.sres,
2759 g_pars.vec.kc,
2760 g_pars.vec.ik,
2761 g_pars.vec.ck,
2762 g_pars.vec.autn,
2763 g_pars.vec.res));
2764 /* send new key material */
2765 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2766
2767 /* wait for the new Auth Request */
2768 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2769 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002770 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002771 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2772 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2773 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2774 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2775 valueField := substr(g_pars.vec.res, 0, 4)
2776 };
2777 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2778 elementIdentifier := '21'O,
2779 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2780 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2781 };
2782 l3_mo := valueof(auth_ciph_resp);
2783 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2784 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2785 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2786 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2787 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002788 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002789 deactivate(di);
2790
2791 /* Expect SGSN to perform LU with HLR */
2792 f_gmm_gsup_lu_isd();
2793
Harald Welte955aa942019-05-03 01:29:29 +02002794 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2795 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002796 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002797 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002798 setverdict(pass);
2799}
2800
2801testcase TC_attach_usim_resync() runs on test_CT {
2802 /* MS -> SGSN: Attach Request
2803 * MS <- SGSN: Identity Request IMSI
2804 * MS -> SGSN: Identity Response IMSI
2805 * MS <- SGSN: Identity Request IMEI
2806 * MS -> SGSN: Identity Response IMEI
2807 * HLR<- SGSN: SAI Request
2808 * HLR-> SGSN: SAI Response
2809 * MS <- SGSN: Auth Request
2810 * MS -> SGSN: Auth Failure (with AUTS)
2811 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2812 * HLR-> SGSN: SAI Response (new key material)
2813 * MS <- SGSN: Auth Request (new key material)
2814 * MS -> SGSN: Auth Response
2815 * MS <- SGSN: Attach Accept
2816 * MS -> SGSN: Attach Complete
2817 */
2818 var BSSGP_ConnHdlr vc_conn;
2819 f_init();
2820 f_sleep(1.0);
2821 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2822 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002823 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002824}
2825
Harald Weltea05b8072019-04-23 22:35:05 +02002826
2827/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2828private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2829 f_gmm_attach(false, false);
2830 f_sleep(1.0);
2831 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2832 /* try to detach to check if SGSN is still alive */
2833 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2834}
2835testcase TC_llc_null() runs on test_CT {
2836 var BSSGP_ConnHdlr vc_conn;
2837 f_init();
2838 f_sleep(1.0);
2839 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2840 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002841 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002842}
2843
Harald Welte645a1512019-04-23 23:18:23 +02002844/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2845private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2846 f_gmm_attach(false, false);
2847 f_sleep(1.0);
2848 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002849 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002850 setverdict(pass);
2851}
2852testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2853 var BSSGP_ConnHdlr vc_conn;
2854 f_init();
2855 f_sleep(1.0);
2856 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2857 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002858 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002859}
2860
2861/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2862private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2863 f_gmm_attach(false, false);
2864 f_sleep(1.0);
2865 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002866 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002867 setverdict(pass);
2868}
2869testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2870 var BSSGP_ConnHdlr vc_conn;
2871 f_init();
2872 f_sleep(1.0);
2873 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2874 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002875 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002876}
2877
Harald Welte2aaac1b2019-05-02 10:02:53 +02002878/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2879private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2880 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2881 var template (value) XID_Information xid;
2882 var template XID_Information xid_rx;
2883
2884 /* first perform regular attach */
2885 f_TC_attach(id);
2886 /* then activate PDP context */
2887 f_pdp_ctx_act(apars);
2888
2889 /* start MO XID */
2890 xid := { ts_XID_L3(''O) };
2891 xid_rx := { tr_XID_L3(''O) };
2892 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2893 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002894 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002895 [] as_xid(apars);
2896 }
2897 setverdict(pass);
2898}
2899testcase TC_xid_empty_l3() runs on test_CT {
2900 var BSSGP_ConnHdlr vc_conn;
2901 f_init();
2902 f_sleep(1.0);
2903 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2904 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002905 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002906}
2907
2908private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2909 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2910 var template (value) XID_Information xid;
2911 var template XID_Information xid_rx;
2912
2913 /* first perform regular attach */
2914 f_TC_attach(id);
2915 /* then activate PDP context */
2916 f_pdp_ctx_act(apars);
2917
2918 /* start MO XID */
2919 xid := { ts_XID_N201U(1234) };
2920 xid_rx := { tr_XID_N201U(1234) };
2921 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2922 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002923 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002924 [] as_xid(apars);
2925 }
2926 setverdict(pass);
2927}
2928testcase TC_xid_n201u() runs on test_CT {
2929 var BSSGP_ConnHdlr vc_conn;
2930 f_init();
2931 f_sleep(1.0);
2932 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2933 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002934 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002935}
2936
Alexander Couzens6bee0872019-05-11 01:48:50 +02002937private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2938 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2939
2940 /* first perform regular attach */
2941 f_TC_attach(id);
2942 /* then activate PDP context */
2943 f_pdp_ctx_act(apars);
2944 /* do a normal detach */
2945 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2946}
2947
2948testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2949 /* MS -> SGSN: Attach Request
2950 * MS <-> SGSN: [..]
2951 * MS -> SGSN: Attach Complete
2952 * MS -> SGSN: PDP Activate Request
2953 * MS <- SGSN: PDP Activate Accept
2954 * MS -> SGSN: GMM Detach Request
2955 * MS <- SGSN: GMM Detach Accept
2956 */
2957 var BSSGP_ConnHdlr vc_conn;
2958 f_init();
2959 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2960 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002961 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002962}
Harald Welte645a1512019-04-23 23:18:23 +02002963
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002964private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2965 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2966 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2967 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2968 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2969 var PDU_L3_SGSN_MS l3_mt;
2970
2971 f_send_l3(attach_req, 0);
2972
2973 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2974
2975 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2976 alt {
2977 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2978 setverdict(pass);
2979 }
2980 [] BSSGP[0].receive { repeat; }
2981 }
2982}
2983
2984/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2985 * See OS#3957 and OS#4245 for more information.
2986 */
2987testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2988 /*
2989 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2990 * MS <-- SGSN: Identity Request (IMEI)
2991 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2992 */
2993 var BSSGP_ConnHdlr vc_conn;
2994 f_init();
2995 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2996 vc_conn.done;
2997 f_cleanup();
2998}
2999
Harald Welte8e5932e2020-06-17 22:12:54 +02003000private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3001var PDU_BSSGP rx;
3002[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3003 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3004 mtc.stop;
3005 }
3006}
3007
3008/* SUSPEND, then DL traffic: should not pass + no paging expected */
3009private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3010 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3011 var default d;
3012
3013 /* first perform regular attach */
3014 f_TC_attach(id);
3015 /* then activate PDP context */
3016 f_pdp_ctx_act(apars);
3017 /* then transceive a downlink PDU */
3018 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3019
3020 /* now suspend GPRS */
3021 f_bssgp_suspend();
3022
3023 d := activate(as_nopaging_ps());
3024
3025 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3026 * nor any related paging requests */
3027 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3028
3029 deactivate(d);
3030}
3031testcase TC_suspend_nopaging() runs on test_CT {
3032 var BSSGP_ConnHdlr vc_conn;
3033 f_init();
3034 f_sleep(1.0);
3035 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3036 vc_conn.done;
3037 f_cleanup();
3038}
3039
3040
3041/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3042private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3043 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3044 var OCT1 susp_ref;
3045 var default d;
3046
3047 /* first perform regular attach */
3048 f_TC_attach(id);
3049 /* then activate PDP context */
3050 f_pdp_ctx_act(apars);
3051 /* then transceive a downlink PDU */
3052 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3053
3054 /* now suspend GPRS */
3055 susp_ref := f_bssgp_suspend();
3056
3057 d := activate(as_nopaging_ps());
3058
3059 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3060 * nor any related paging requests */
3061 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3062
3063 deactivate(d);
3064
3065 /* resume GPRS */
3066 f_bssgp_resume(susp_ref);
3067
3068 /* now data should be flowing again */
3069 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3070}
3071testcase TC_suspend_resume() runs on test_CT {
3072 var BSSGP_ConnHdlr vc_conn;
3073 f_init();
3074 f_sleep(1.0);
3075 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3076 vc_conn.done;
3077 f_cleanup();
3078}
3079
3080/* SUSPEND, then RAU: data expected to flow after implicit resume */
3081private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3082 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3083 var default d;
3084
3085 /* first perform regular attach */
3086 f_TC_attach(id);
3087 /* then activate PDP context */
3088 f_pdp_ctx_act(apars);
3089 /* then transceive a downlink PDU */
3090 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3091
3092 /* now suspend GPRS */
3093 f_bssgp_suspend();
3094
3095 d := activate(as_nopaging_ps());
3096
3097 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3098 * nor any related paging requests */
3099 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3100
3101 deactivate(d);
3102
3103 /* perform RAU (implicit RESUME) */
3104 f_routing_area_update(g_pars.ra);
3105
3106 /* now data should be flowing again */
3107 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3108
3109}
3110testcase TC_suspend_rau() runs on test_CT {
3111 var BSSGP_ConnHdlr vc_conn;
3112 f_init();
3113 f_sleep(1.0);
3114 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3115 vc_conn.done;
3116 f_cleanup();
3117}
3118
3119
3120/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3121private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3122 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3123 var default d;
3124
3125 /* first perform regular attach */
3126 f_TC_attach(id);
3127 /* then activate PDP context */
3128 f_pdp_ctx_act(apars);
3129 /* then transceive a downlink PDU */
3130 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3131
3132 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3133 f_sleep(5.0);
3134
3135 /* now data should be flowing again, but with PS PAGING */
3136 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3137 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3138
3139 /* FIXME: simulate paging response */
3140 /* FIXME: verify PDU actually arrives only after paging response was successful */
3141
3142}
3143testcase TC_paging_ps() runs on test_CT {
3144 var BSSGP_ConnHdlr vc_conn;
3145 f_init();
3146 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3147 f_sleep(1.0);
3148 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3149 vc_conn.done;
3150 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3151 f_cleanup();
3152}
3153
Philipp Maier7df55e02020-12-14 23:46:04 +01003154private function f_TC_bssgp_rim_dummy(charstring id) runs on BSSGP_ConnHdlr {
3155}
3156
3157/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3158 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3159 * other and vice versa. */
3160testcase TC_bssgp_rim_single_report() runs on test_CT {
3161 var BSSGP_ConnHdlr vc_conn;
3162 f_init();
3163 vc_conn := f_start_handler(refers(f_TC_bssgp_rim_dummy), testcasename(), g_gb, 17);
3164 vc_conn.done;
3165
3166 timer T := 2.0;
3167
3168 var template RIM_Routing_Address dst_addr;
3169 var template RIM_Routing_Address src_addr;
3170 var template RAN_Information_Request_RIM_Container req_cont;
3171 var template RAN_Information_RIM_Container res_cont;
3172 var template PDU_BSSGP bssgp_rim_pdu;
3173 var template PDU_BSSGP bssgp_rim_pdu_expect;
3174
3175 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3176 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003177
3178
Philipp Maier7df55e02020-12-14 23:46:04 +01003179 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3180 * based on the cell id in dst_addr to GB interface #1. */
3181 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3182 ts_RIM_Sequence_Number(1),
3183 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3184 ts_RIM_Protocol_Version_Number(1),
3185 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3186 omit);
3187 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3188 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3189 req_cont);
3190 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3191 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3192 tr_RAN_Information_Request_RIM_Container);
3193 RIM[0].send(bssgp_rim_pdu);
3194 T.start;
3195 alt {
3196 [] RIM[1].receive(bssgp_rim_pdu_expect) { }
3197 [] RIM[1].receive {
3198 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3199 }
3200 [] T.timeout {
3201 setverdict(fail, "No BSSGP RIM PDU received");
3202 mtc.stop;
3203 }
3204 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003205
Philipp Maier7df55e02020-12-14 23:46:04 +01003206 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3207 * GB interface #0 */
3208 var octetstring si1 := '198fb100000000000000000000000000007900002b'O;
3209 var octetstring si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
3210 var octetstring si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
3211 var octetstring si := si1 & si3 & si13;
3212
3213 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3214 ts_RIM_Sequence_Number(2),
3215 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3216 ts_RIM_Protocol_Version_Number(1),
3217 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si)),
3218 omit);
3219 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3220 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3221 res_cont);
3222 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3223 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3224 ?);
3225 RIM[1].send(bssgp_rim_pdu);
3226 T.start;
3227 alt {
3228 [] RIM[0].receive(bssgp_rim_pdu_expect) { }
3229 [] RIM[0].receive {
3230 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3231 }
3232 [] T.timeout {
3233 setverdict(fail, "No BSSGP RIM PDU received");
3234 mtc.stop;
3235 }
3236 }
3237
3238 f_cleanup();
3239}
Harald Welte8e5932e2020-06-17 22:12:54 +02003240
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003241/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3242private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3243 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3244
3245 /* first perform regular attach */
3246 f_gmm_attach(false, false, ran_index := 0);
3247 /* then activate PDP context */
3248 f_pdp_ctx_act(apars, ran_index := 0);
3249 /* then transceive a downlink PDU */
3250 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3251 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3252
3253 /* Now attach on different cell: */
3254 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3255 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3256 g_pars.net.expect_auth := false;
3257 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3258 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3259 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3260}
3261testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3262 var BSSGP_ConnHdlr vc_conn;
3263 f_init();
3264 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3265 vc_conn.done;
3266 f_cleanup();
3267}
3268
3269/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3270/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3271private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3272 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3273
3274 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3275 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3276
3277 /* first perform regular attach */
3278 f_gmm_attach(false, false, ran_index := 1);
3279 /* then activate PDP context */
3280 f_pdp_ctx_act(apars, ran_index := 1);
3281 /* then transceive a downlink PDU */
3282 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3283 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3284
3285 /* Now attach on different cell: */
3286 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3287 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3288 g_pars.net.expect_auth := false;
3289 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3290 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3291 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3292}
3293testcase TC_cell_change_different_ci_attach() runs on test_CT {
3294 var BSSGP_ConnHdlr vc_conn;
3295 f_init();
3296 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3297 vc_conn.done;
3298 f_cleanup();
3299}
3300
3301/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3302private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3303 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3304
3305 /* first perform regular attach */
3306 f_gmm_attach(false, false, ran_index := 0);
3307 /* then activate PDP context */
3308 f_pdp_ctx_act(apars, ran_index := 0);
3309 /* then transceive a downlink PDU */
3310 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3311 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3312
3313 /* Send some data over new bvci, it should be silently discarded since
3314 * RAC changed and SGSN expects a RAU to occur in that case */
3315 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3316 var octetstring payload := f_rnd_octstring(200);
3317 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3318 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
3319 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
3320 timer T := 2.0;
3321 T.start;
3322 alt {
3323 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3324 setverdict(fail, "Unexpected GTP message");
3325 }
3326 [] T.timeout { setverdict(pass); }
3327 }
3328
3329 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3330 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3331 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3332}
3333testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3334 var BSSGP_ConnHdlr vc_conn;
3335 f_init();
3336 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3337 vc_conn.done;
3338 f_cleanup();
3339}
3340
3341/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3342/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3343private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3344 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3345
3346 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3347 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3348
3349 /* first perform regular attach */
3350 f_gmm_attach(false, false, ran_index := 1);
3351 /* then activate PDP context */
3352 f_pdp_ctx_act(apars, ran_index := 1);
3353 /* then transceive a downlink PDU */
3354 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3355 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3356
3357 /* Now attach on different cell: */
3358 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3359 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3360
3361 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3362 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3363}
3364testcase TC_cell_change_different_ci_data() runs on test_CT {
3365 var BSSGP_ConnHdlr vc_conn;
3366 f_init();
3367 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3368 vc_conn.done;
3369 f_cleanup();
3370}
3371
Harald Welte5ac31492018-02-15 20:39:13 +01003372control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003373 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003374 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003375 execute( TC_attach_umts_aka_umts_res() );
3376 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003377 execute( TC_attach_auth_id_timeout() );
3378 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003379 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003380 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003381 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003382 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003383 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003384 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003385 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003386 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003387 execute( TC_attach_closed_add_vty(), 20.0 );
3388 execute( TC_attach_check_subscriber_list(), 20.0 );
3389 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003390 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003391 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3392 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3393 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3394 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003395 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003396 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003397 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003398 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003399 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003400 execute( TC_detach_unknown_nopoweroff() );
3401 execute( TC_detach_unknown_poweroff() );
3402 execute( TC_detach_nopoweroff() );
3403 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003404 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003405 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003406 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003407 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003408 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003409 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003410 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003411 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003412 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003413 execute( TC_attach_restart_ctr_echo() );
3414 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003415 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003416 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3417 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003418 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003419 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003420 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003421
Harald Welte2aaac1b2019-05-02 10:02:53 +02003422 execute( TC_xid_empty_l3() );
3423 execute( TC_xid_n201u() );
3424
Harald Weltea05b8072019-04-23 22:35:05 +02003425 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003426 execute( TC_llc_sabm_dm_llgmm() );
3427 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003428
Harald Welte8e5932e2020-06-17 22:12:54 +02003429 execute( TC_suspend_nopaging() );
3430 execute( TC_suspend_resume() );
3431 execute( TC_suspend_rau() );
3432 execute( TC_paging_ps() );
3433
Philipp Maier7df55e02020-12-14 23:46:04 +01003434 execute( TC_bssgp_rim_single_report() );
3435
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003436 execute( TC_cell_change_different_rai_ci_attach() );
3437 execute( TC_cell_change_different_rai_ci_data() );
3438 execute( TC_cell_change_different_ci_attach() );
3439 execute( TC_cell_change_different_ci_data() );
3440
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003441 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3442 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003443}
Harald Welte96a33b02018-02-04 10:36:22 +01003444
3445
3446
3447}