blob: 6c8ea6108f1a4cbfdc917b5ea7085fdaafc9e34a [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);
Harald Weltedd9fb842021-02-16 20:21:22 +0100771 /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB
772 * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */
773 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100774 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100775 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200776 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100777 }
Harald Welte04683d02018-02-16 22:43:45 +0100778 g_pars.ra := aa.routingAreaIdentification;
779 if (ispresent(aa.allocatedPTMSI)) {
780 if (not g_pars.net.expect_ptmsi) {
781 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200782 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100783 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100784 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
785 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100786 }
787 if (ispresent(aa.msIdentity)) {
788 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200789 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100790 }
791 /* P-TMSI.sig */
792 if (ispresent(aa.ptmsiSignature)) {
793 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
794 }
795 /* updateTimer */
796 // aa.readyTimer
797 /* T3302, T3319, T3323, T3312_ext, T3324 */
798}
799
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200800function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100801 /* mandatory IE */
802 g_pars.ra := ra.routingAreaId;
803 if (ispresent(ra.allocatedPTMSI)) {
804 if (not g_pars.net.expect_ptmsi) {
805 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200806 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100807 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100808 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
809 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100810 }
811 if (ispresent(ra.msIdentity)) {
812 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200813 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100814 }
815 /* P-TMSI.sig */
816 if (ispresent(ra.ptmsiSignature)) {
817 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
818 }
819 /* updateTimer */
820 // aa.readyTimer
821 /* T3302, T3319, T3323, T3312_ext, T3324 */
822}
823
824
Harald Welte5a4fa042018-02-16 20:59:21 +0100825function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
826 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
827}
828
Harald Welte23178c52018-02-17 09:36:33 +0100829/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700830private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100831 if (ispresent(g_pars.p_tmsi)) {
832 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
833 } else {
834 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
835 }
836}
837
Harald Welte311ec272018-02-17 09:40:03 +0100838private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100839 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100840 /* Expect MSC to perform LU with HLR */
841 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100842 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
843 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
844 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100845 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
846 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
847}
848
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100849friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
850 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
851 var RoutingAreaIdentificationV old_ra_val;
852 var template PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200853 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100854
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100855 if (istemplatekind(old_ra, "omit")) {
856 old_ra_val := f_random_RAI();
857 } else {
858 old_ra_val := valueof(old_ra);
859 }
860
861 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200862 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
863 * 3G auth vectors */
864 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
865 /* The thing is, if the solSACapability is 'omit', then the
866 * revisionLevelIndicatior is at the wrong place! */
867 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
868
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200869 f_send_l3(attach_req, ran_index);
870 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200871 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100872 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100873
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200874 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100875 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200876
Harald Welte04683d02018-02-16 22:43:45 +0100877 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200878 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200879
880 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200881 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200882 as_iu_release_compl_disc();
883 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200884
885 /* Race condition
886 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
887 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
888 * arrived before it. This results in a test case failure.
889 * Delay execution by 50 ms
890 */
891 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200892}
893
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200894friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
895 timer T := 5.0;
896 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100897 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 +0200898 T.start;
899 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100900 [] 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 +0200901 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
902 }
Harald Welte9b461a92020-12-10 23:41:14 +0100903 [] 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 +0200904 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
905 mtc.stop;
906 }
907 [] T.timeout {
908 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
909 mtc.stop;
910 }
911 }
912 return '00'O;
913}
914
915friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
916 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100917 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 +0200918 T.start;
919 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100920 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
921 [] 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 +0200922?)) {
923 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
924 mtc.stop;
925 }
926 [] T.timeout {
927 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
928 mtc.stop;
929 }
930 }
931}
932
933
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200934private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
935 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100936 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100937}
938
939testcase TC_attach() runs on test_CT {
940 var BSSGP_ConnHdlr vc_conn;
941 f_init();
942 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200943 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100944 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200945 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100946}
947
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100948testcase TC_attach_mnc3() runs on test_CT {
949 var BSSGP_ConnHdlr vc_conn;
950 f_init('023042'H);
951 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200952 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100953 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200954 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100955}
956
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200957private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
958 f_gmm_attach(true, false);
959 setverdict(pass);
960}
961testcase TC_attach_umts_aka_umts_res() runs on test_CT {
962 var BSSGP_ConnHdlr vc_conn;
963 f_init();
964 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200965 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200966 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200967 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200968}
969
970private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
971 f_gmm_attach(true, true);
972 setverdict(pass);
973}
974testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
975 var BSSGP_ConnHdlr vc_conn;
976 f_init();
977 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200978 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200979 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200980 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200981}
982
Harald Welte5b7c8122018-02-16 21:48:17 +0100983/* MS never responds to ID REQ, expect ATTACH REJECT */
984private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100985 var RoutingAreaIdentificationV old_ra := f_random_RAI();
986
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200987 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100988 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200989 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100990 /* don't send ID Response */
991 repeat;
992 }
Harald Welte955aa942019-05-03 01:29:29 +0200993 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100994 setverdict(pass);
995 }
Harald Welte955aa942019-05-03 01:29:29 +0200996 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100997 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200998 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100999 }
1000 }
1001}
1002testcase TC_attach_auth_id_timeout() runs on test_CT {
1003 var BSSGP_ConnHdlr vc_conn;
1004 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001005 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 +01001006 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001007 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001008}
1009
1010/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1011private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001012 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1013
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001014 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001015 alt {
1016 [] as_mm_identity();
1017 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1018 }
1019 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001020 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001021 setverdict(pass);
1022}
1023testcase TC_attach_auth_sai_timeout() runs on test_CT {
1024 var BSSGP_ConnHdlr vc_conn;
1025 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001026 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001027 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001028 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001029}
1030
Harald Weltefe253882018-02-17 09:25:00 +01001031/* HLR rejects SAI, expect ATTACH REJECT */
1032private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001033 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1034
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001035 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001036 alt {
1037 [] as_mm_identity();
1038 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1039 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1040 }
1041 }
Harald Welte955aa942019-05-03 01:29:29 +02001042 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001043 setverdict(pass);
1044}
1045testcase TC_attach_auth_sai_reject() runs on test_CT {
1046 var BSSGP_ConnHdlr vc_conn;
1047 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001048 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001049 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001050 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001051}
1052
Harald Welte5b7c8122018-02-16 21:48:17 +01001053/* HLR never responds to UL REQ, expect ATTACH REJECT */
1054private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001055 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001056 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1057
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001058 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001059 f_gmm_auth();
1060 /* Expect MSC to perform LU with HLR */
1061 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1062 /* Never follow-up with ISD_REQ or UL_RES */
1063 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001064 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001065 setverdict(pass);
1066 }
Harald Welte955aa942019-05-03 01:29:29 +02001067 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1068 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001069 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001070 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001071 }
1072 }
1073}
1074testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1075 var BSSGP_ConnHdlr vc_conn;
1076 f_init();
1077 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001078 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001079 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001080 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001081}
1082
Harald Welteb7c14e92018-02-17 09:29:16 +01001083/* HLR rejects UL REQ, expect ATTACH REJECT */
1084private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001085 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001086 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1087
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001088 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001089 f_gmm_auth();
1090 /* Expect MSC to perform LU with HLR */
1091 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1092 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1093 }
1094 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001095 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001096 setverdict(pass);
1097 }
Harald Welte955aa942019-05-03 01:29:29 +02001098 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1099 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001100 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001101 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001102 }
1103 }
1104}
1105testcase TC_attach_gsup_lu_reject() runs on test_CT {
1106 var BSSGP_ConnHdlr vc_conn;
1107 f_init();
1108 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001109 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001110 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001111 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001112}
1113
1114
Harald Welte3823e2e2018-02-16 21:53:48 +01001115/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1116private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001117 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001118 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1119
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001120 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001121 f_gmm_auth();
1122 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001123 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001124
Harald Welte955aa942019-05-03 01:29:29 +02001125 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1126 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001127 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001128 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001129 setverdict(pass);
1130}
Harald Welte3823e2e2018-02-16 21:53:48 +01001131testcase TC_attach_combined() runs on test_CT {
1132 var BSSGP_ConnHdlr vc_conn;
1133 f_init();
1134 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001135 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001136 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001137 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001138}
1139
Harald Welte76dee092018-02-16 22:12:59 +01001140/* Attempt of GPRS ATTACH in 'accept all' mode */
1141private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001142 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001143 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1144
1145 g_pars.net.expect_auth := false;
1146
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001147 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001148 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001149 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1150 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001151 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001152 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001153 setverdict(pass);
1154}
1155testcase TC_attach_accept_all() runs on test_CT {
1156 var BSSGP_ConnHdlr vc_conn;
1157 f_init();
1158 f_sleep(1.0);
1159 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001160 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001161 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001162 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001163}
Harald Welte5b7c8122018-02-16 21:48:17 +01001164
Harald Welteb2124b22018-02-16 22:26:56 +01001165/* Attempt of GPRS ATTACH in 'accept all' mode */
1166private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001167 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1168
1169 /* Simulate a foreign IMSI */
1170 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001171 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001172
1173 g_pars.net.expect_auth := false;
1174
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001175 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001176 alt {
1177 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001178 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001179 setverdict(pass);
1180 }
Harald Welte955aa942019-05-03 01:29:29 +02001181 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001182 setverdict(pass);
1183 }
Harald Welte955aa942019-05-03 01:29:29 +02001184 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001185 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001186 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001187 }
Harald Welteb2124b22018-02-16 22:26:56 +01001188 }
1189}
1190testcase TC_attach_closed() runs on test_CT {
1191 var BSSGP_ConnHdlr vc_conn;
1192 f_init();
1193 f_sleep(1.0);
1194 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1195 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001196 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001197 vc_conn.done;
1198 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001199 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001200 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001201 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001202}
1203
Harald Welte04683d02018-02-16 22:43:45 +01001204/* Routing Area Update from Unknown TLLI -> REJECT */
1205private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001206 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1207
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001208 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 +01001209 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001210 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001211 setverdict(pass);
1212 }
1213 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001214 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001215 }
1216}
1217testcase TC_rau_unknown() runs on test_CT {
1218 var BSSGP_ConnHdlr vc_conn;
1219 f_init();
1220 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001221 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001222 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001223 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001224}
1225
Harald Welte91636de2018-02-17 10:16:14 +01001226private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001227 /* first perform regular attach */
1228 f_TC_attach(id);
1229
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001230 f_routing_area_update(g_pars.ra);
1231
Harald Welte91636de2018-02-17 10:16:14 +01001232}
1233testcase TC_attach_rau() runs on test_CT {
1234 var BSSGP_ConnHdlr vc_conn;
1235 f_init();
1236 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001237 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001238 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001239 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001240}
Harald Welte04683d02018-02-16 22:43:45 +01001241
Harald Welte6abb9fe2018-02-17 15:24:48 +01001242/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001243function 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 +02001244 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001245 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001246 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001247 if (expect_purge) {
1248 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1249 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1250 }
1251 T.start;
1252 alt {
1253 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1254 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001255 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001256 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001257 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001258 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001259 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001260 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001261 /* TODO: check if any PDP contexts are deactivated on network side? */
1262 }
1263 [power_off] T.timeout {
1264 setverdict(pass);
1265 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001266 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001267 g_pars.ra := omit;
1268 setverdict(pass);
1269 /* TODO: check if any PDP contexts are deactivated on network side? */
1270 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001271 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001272 if (power_off) {
1273 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1274 } else {
1275 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1276 }
1277 mtc.stop;
1278 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001279 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001280 }
1281}
1282
1283/* IMSI DETACH (non-power-off) for unknown TLLI */
1284private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1285 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1286}
1287testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1288 var BSSGP_ConnHdlr vc_conn;
1289 f_init();
1290 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001291 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001292 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001293 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001294}
1295
1296/* IMSI DETACH (power-off) for unknown TLLI */
1297private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1298 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1299}
1300testcase TC_detach_unknown_poweroff() runs on test_CT {
1301 var BSSGP_ConnHdlr vc_conn;
1302 f_init();
1303 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001304 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001305 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001306 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001307}
1308
1309/* IMSI DETACH (non-power-off) for known TLLI */
1310private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1311 /* first perform regular attach */
1312 f_TC_attach(id);
1313
1314 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1315}
1316testcase TC_detach_nopoweroff() runs on test_CT {
1317 var BSSGP_ConnHdlr vc_conn;
1318 f_init();
1319 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001320 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001321 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001322 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001323}
1324
1325/* IMSI DETACH (power-off) for known TLLI */
1326private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1327 /* first perform regular attach */
1328 f_TC_attach(id);
1329
1330 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1331}
1332testcase TC_detach_poweroff() runs on test_CT {
1333 var BSSGP_ConnHdlr vc_conn;
1334 f_init();
1335 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001336 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001337 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001338 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001339}
1340
Harald Welteeded9ad2018-02-17 20:57:34 +01001341type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001342 BIT3 tid, /* L3 Transaction ID */
1343 BIT4 nsapi, /* SNDCP NSAPI */
1344 BIT4 sapi, /* LLC SAPI */
1345 QoSV qos, /* QoS parameters */
1346 PDPAddressV addr, /* IP address */
1347 octetstring apn optional, /* APN name */
1348 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1349 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001350 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001351 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001352
Harald Welte822f9102018-02-18 20:39:06 +01001353 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1354 OCT4 ggsn_tei_u, /* GGSN TEI User */
1355 octetstring ggsn_ip_c, /* GGSN IP Control */
1356 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001357 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001358
Harald Welte822f9102018-02-18 20:39:06 +01001359 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1360 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1361 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1362 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001363};
1364
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001365
1366private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1367 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1368 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1369 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1370 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1371 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1372 f_gtp_register_teid(apars.ggsn_tei_c);
1373 f_gtp_register_teid(apars.ggsn_tei_u);
1374}
1375
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001376function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001377runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001378 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1379 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001380 var template Recovery_gtpc recovery := omit;
1381
1382 if (send_recovery) {
1383 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1384 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001385
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001386 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 +02001387 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001388 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1389 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1390 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1391 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1392 apars.sgsn_tei_c, apars.gtp_resp_cause,
1393 apars.ggsn_tei_c, apars.ggsn_tei_u,
1394 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001395 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1396 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001397 }
1398 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001399 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001400 setverdict(pass);
1401 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001402 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001403 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001404 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001405 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001406 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001407 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001408 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001409 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001410 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001411 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1412 mtc.stop;
1413 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001414 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001415 setverdict(pass);
1416 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001417 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001418 }
1419}
1420
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001421function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001422runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001423 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1424 var Gtp1cUnitdata g_ud;
1425
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001426 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001427 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1428 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001429 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001430 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1431 }
1432 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001433 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001434 setverdict(pass);
1435 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001436 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001437 }
1438}
1439
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001440function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001441runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001442 var Gtp1cUnitdata g_ud;
1443 var integer seq_nr := 23;
1444 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1445
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001446 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001447 if (error_ind) {
1448 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1449 } else {
1450 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1451 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001452
1453 timer T := 5.0;
1454 T.start;
1455
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001456 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001457 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1458 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001459 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001460 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1461 repeat;
1462 }
1463 [] T.timeout {
1464 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1465 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001466 }
1467}
1468
Harald Welte6f203162018-02-18 22:04:55 +01001469
Harald Welteeded9ad2018-02-17 20:57:34 +01001470/* Table 10.5.156/3GPP TS 24.008 */
1471template (value) QoSV t_QosDefault := {
1472 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1473 delayClass := '100'B, /* best effort */
1474 spare1 := '00'B,
1475 precedenceClass := '010'B, /* normal */
1476 spare2 := '0'B,
1477 peakThroughput := '0000'B, /* subscribed */
1478 meanThroughput := '00000'B, /* subscribed */
1479 spare3 := '000'B,
1480 deliverErroneusSDU := omit,
1481 deliveryOrder := omit,
1482 trafficClass := omit,
1483 maxSDUSize := omit,
1484 maxBitrateUplink := omit,
1485 maxBitrateDownlink := omit,
1486 sduErrorRatio := omit,
1487 residualBER := omit,
1488 trafficHandlingPriority := omit,
1489 transferDelay := omit,
1490 guaranteedBitRateUplink := omit,
1491 guaranteedBitRateDownlink := omit,
1492 sourceStatisticsDescriptor := omit,
1493 signallingIndication := omit,
1494 spare4 := omit,
1495 maxBitrateDownlinkExt := omit,
1496 guaranteedBitRateDownlinkExt := omit,
1497 maxBitrateUplinkExt := omit,
1498 guaranteedBitRateUplinkExt := omit,
1499 maxBitrateDownlinkExt2 := omit,
1500 guaranteedBitRateDownlinkExt2 := omit,
1501 maxBitrateUplinkExt2 := omit,
1502 guaranteedBitRateUplinkExt2 := omit
1503}
1504
1505/* 10.5.6.4 / 3GPP TS 24.008 */
1506template (value) PDPAddressV t_AddrIPv4dyn := {
1507 pdpTypeOrg := '0001'B, /* IETF */
1508 spare := '0000'B,
1509 pdpTypeNum := '21'O, /* IPv4 */
1510 addressInfo := omit
1511}
1512template (value) PDPAddressV t_AddrIPv6dyn := {
1513 pdpTypeOrg := '0001'B, /* IETF */
1514 spare := '0000'B,
1515 pdpTypeNum := '53'O, /* IPv6 */
1516 addressInfo := omit
1517}
1518
Harald Welte37692d82018-02-18 15:21:34 +01001519template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001520 tid := '000'B,
1521 nsapi := '0101'B, /* < 5 are reserved */
1522 sapi := '0011'B, /* 3/5/9/11 */
1523 qos := t_QosDefault,
1524 addr := t_AddrIPv4dyn,
1525 apn := omit,
1526 pco := omit,
1527 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001528 gtp_resp_cause := int2oct(128, 1),
1529 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001530
1531 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001532 ggsn_tei_c := f_rnd_octstring(4),
1533 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001534 ggsn_ip_c := f_inet_addr(ggsn_ip),
1535 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001536 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001537
Harald Welteeded9ad2018-02-17 20:57:34 +01001538 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001539 sgsn_tei_u := omit,
1540 sgsn_ip_c := omit,
1541 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001542}
1543
Harald Welte37692d82018-02-18 15:21:34 +01001544template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1545 connId := 1,
1546 remName := f_inet_ntoa(ip),
1547 remPort := GTP1U_PORT
1548}
1549
1550template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1551 connId := 1,
1552 remName := f_inet_ntoa(ip),
1553 remPort := GTP1C_PORT
1554}
1555
1556private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1557 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1558 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1559}
1560
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001561private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1562 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001563 repeat;
1564 }
1565}
1566
1567template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1568 pDU_SN_UNITDATA := {
1569 nsapi := nsapi,
1570 moreBit := ?,
1571 snPduType := '1'B,
1572 firstSegmentIndicator := ?,
1573 spareBit := ?,
1574 pcomp := ?,
1575 dcomp := ?,
1576 npduNumber := ?,
1577 segmentNumber := ?,
1578 npduNumberContinued := ?,
1579 dataSegmentSnUnitdataPdu := payload
1580 }
1581}
1582
1583/* simple case: single segment, no compression */
1584template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1585 pDU_SN_UNITDATA := {
1586 nsapi := nsapi,
1587 moreBit := '0'B,
1588 snPduType := '1'B,
1589 firstSegmentIndicator := '1'B,
1590 spareBit := '0'B,
1591 pcomp := '0000'B,
1592 dcomp := '0000'B,
1593 npduNumber := '0000'B,
1594 segmentNumber := '0000'B,
1595 npduNumberContinued := '00'O,
1596 dataSegmentSnUnitdataPdu := payload
1597 }
1598}
1599
1600/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001601private 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 +02001602runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001603 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001604 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1605 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001606 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001607 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1608 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001609 [] as_xid(apars, ran_index);
1610 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001611 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1612 [expect_fwd] T.timeout {
1613 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1614 mtc.stop;
1615 }
1616 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1617 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1618 mtc.stop;
1619 }
1620 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001621 }
1622}
1623
Harald Welte64d6b512020-06-17 16:42:00 +02001624/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001625private 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 +02001626runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001627 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1628 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1629 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001630 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001631 /* Expect PDU via GTP from SGSN on simulated GGSN */
1632 alt {
1633 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1634 }
1635}
1636
Harald Welteeded9ad2018-02-17 20:57:34 +01001637private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001638 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001639
1640 /* first perform regular attach */
1641 f_TC_attach(id);
1642
1643 f_pdp_ctx_act(apars);
1644}
1645testcase TC_attach_pdp_act() runs on test_CT {
1646 var BSSGP_ConnHdlr vc_conn;
1647 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001648 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001649 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001650 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001651}
Harald Welteb2124b22018-02-16 22:26:56 +01001652
Harald Welte835b15f2018-02-18 14:39:11 +01001653/* PDP Context activation for not-attached subscriber; expect fail */
1654private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001655 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001656 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 +01001657 apars.apn, apars.pco));
1658 alt {
1659 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001660 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001661 setverdict(pass);
1662 }
1663 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1664 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001665 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001666 }
Harald Welte955aa942019-05-03 01:29:29 +02001667 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001668 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001669 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001670 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001671 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001672 }
1673}
1674testcase TC_pdp_act_unattached() runs on test_CT {
1675 var BSSGP_ConnHdlr vc_conn;
1676 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001677 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001678 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001679 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001680}
1681
Harald Welte37692d82018-02-18 15:21:34 +01001682/* ATTACH + PDP CTX ACT + user plane traffic */
1683private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1684 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1685
1686 /* first perform regular attach */
1687 f_TC_attach(id);
1688 /* then activate PDP context */
1689 f_pdp_ctx_act(apars);
1690 /* then transceive a downlink PDU */
1691 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1692 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1693}
1694testcase TC_attach_pdp_act_user() runs on test_CT {
1695 var BSSGP_ConnHdlr vc_conn;
1696 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001697 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001698 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001699 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001700}
1701
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001702/* ATTACH + PDP CTX ACT; reject from GGSN */
1703private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1704 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1705
1706 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1707 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1708
1709 /* first perform regular attach */
1710 f_TC_attach(id);
1711 /* then activate PDP context */
1712 f_pdp_ctx_act(apars);
1713}
1714testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1715 var BSSGP_ConnHdlr vc_conn;
1716 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001717 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001718 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001719 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001720}
Harald Welte835b15f2018-02-18 14:39:11 +01001721
Harald Welte6f203162018-02-18 22:04:55 +01001722/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1723private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1724 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1725
1726 /* first perform regular attach */
1727 f_TC_attach(id);
1728 /* then activate PDP context */
1729 f_pdp_ctx_act(apars);
1730 /* then transceive a downlink PDU */
1731 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1732 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1733
1734 f_pdp_ctx_deact_mo(apars, '00'O);
1735}
1736testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1737 var BSSGP_ConnHdlr vc_conn;
1738 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001739 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user_deact_mo), testcasename(), g_gb, 21);
Harald Welte6f203162018-02-18 22:04:55 +01001740 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001741 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001742}
1743
Harald Welte57b9b7f2018-02-18 22:28:13 +01001744/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1745private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1746 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1747
1748 /* first perform regular attach */
1749 f_TC_attach(id);
1750 /* then activate PDP context */
1751 f_pdp_ctx_act(apars);
1752 /* then transceive a downlink PDU */
1753 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1754 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1755
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001756 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001757}
1758testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1759 var BSSGP_ConnHdlr vc_conn;
1760 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001761 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 +01001762 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001763 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001764}
1765
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001766/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1767private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1768 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1769 var Gtp1cUnitdata g_ud;
1770 var integer i;
1771 var OCT1 cause_regular_deact := '24'O;
1772
1773 /* first perform regular attach + PDP context act */
1774 f_TC_attach(id);
1775 f_pdp_ctx_act(apars);
1776
1777 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1778 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1779
1780 for (i := 0; i < 2; i := i+1) {
1781 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1782 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1783 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1784 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1785 }
1786 }
1787
1788 alt {
1789 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1790 setverdict(pass);
1791 }
1792 [] as_xid(apars, 0);
1793 }
1794
1795 /* Make sure second DeactPdpAccept is sent: */
1796 timer T := 2.0;
1797 T.start;
1798 alt {
1799 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1800 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1801 }
1802 [] T.timeout {
1803 setverdict(pass);
1804 }
1805 }
1806
1807 setverdict(pass);
1808}
1809testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1810 var BSSGP_ConnHdlr vc_conn;
1811 f_init();
1812 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1813 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001814 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001815}
1816
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001817/* ATTACH + ATTACH (2nd) */
1818private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1819 g_pars.t_guard := 5.0;
1820
1821 /* first perform regular attach */
1822 f_TC_attach(id);
1823
1824 /* second to perform regular attach */
1825 f_TC_attach(id);
1826}
1827
1828
1829testcase TC_attach_second_attempt() runs on test_CT {
1830 var BSSGP_ConnHdlr vc_conn;
1831 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001832 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001833 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001834 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001835}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001836
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001837private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1838 var Gtp1cUnitdata g_ud;
1839 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1840 var integer seq_nr;
1841
1842 /* first perform regular attach */
1843 f_TC_attach(id);
1844 /* then activate PDP context */
1845 f_pdp_ctx_act(apars);
1846
1847 /* Wait to receive first echo request and send initial Restart counter */
1848 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1849 BSSGP[0].clear;
1850 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1851 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1852 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1853 }
1854
1855 /* At some point next echo request not answered will timeout and SGSN
1856 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1857 timer T := 3.0 * 6.0 + 16.0;
1858 T.start;
1859 alt {
1860 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1861 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1862 setverdict(pass);
1863 }
1864 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1865 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1866 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1867 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1868 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1869 repeat;
1870 }
1871 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1872 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1873 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1874 repeat;
1875 }
1876 [] T.timeout {
1877 setverdict(fail, "BSSGP DeactPdpReq not received");
1878 mtc.stop;
1879 }
1880 [] as_xid(apars);
1881 }
1882 T.stop
1883
1884 setverdict(pass);
1885}
1886/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1887testcase TC_attach_echo_timeout() runs on test_CT {
1888 var BSSGP_ConnHdlr vc_conn;
1889 g_use_echo := true;
1890 f_init();
1891 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1892 vc_conn.done;
1893 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001894 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001895}
1896
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001897private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001898 var Gtp1cUnitdata g_ud;
1899 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1900
1901 /* first perform regular attach */
1902 f_TC_attach(id);
1903 /* Activate a pdp context against the GGSN */
1904 f_pdp_ctx_act(apars);
1905 /* Wait to receive first echo request and send initial Restart counter */
1906 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1907 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1908 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1909 }
1910 /* Wait to receive second echo request and send incremented Restart
1911 counter. This will fake a restarted GGSN, and pdp ctx allocated
1912 should be released by SGSN */
1913 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1914 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1915 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1916 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1917 }
1918 var OCT1 cause_network_failure := int2oct(38, 1)
1919 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001920 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001921 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001922 setverdict(pass);
1923 }
1924 [] as_xid(apars);
1925 }
1926 setverdict(pass);
1927}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001928/* ATTACH + trigger Recovery procedure through EchoResp */
1929testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001930 var BSSGP_ConnHdlr vc_conn;
1931 g_use_echo := true
1932 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001933 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 +02001934 vc_conn.done;
1935 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001936 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001937}
1938
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001939private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1940 var Gtp1cUnitdata g_ud;
1941 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1942 var integer seq_nr := 23;
1943 var GtpPeer peer;
1944 /* first perform regular attach */
1945 f_TC_attach(id);
1946
1947 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1948 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1949 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1950 f_pdp_ctx_act(apars, true);
1951
1952 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1953/* received. */
1954 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1955
1956 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1957 would be great to have an active pdp context here before triggering
1958 Recovery, and making sure the the DEACT request is sent by the SGSN.
1959 */
1960
1961 /* Activate a pdp context against the GGSN, send incremented Recovery
1962 IE. This should trigger the recovery path, but still this specific
1963 CTX activation should work. */
1964 apars.exp_rej_cause := omit; /* default value for tests */
1965 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1966 f_pdp_ctx_act(apars, true);
1967
1968 setverdict(pass);
1969}
1970/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1971testcase TC_attach_restart_ctr_create() runs on test_CT {
1972 var BSSGP_ConnHdlr vc_conn;
1973 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001974 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 +02001975 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001976 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001977}
1978
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001979/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1980private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1981 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1982 var integer seq_nr := 23;
1983 var GtpPeer peer;
1984 var integer i;
1985
1986 /* first perform regular attach */
1987 f_TC_attach(id);
1988 /* then activate PDP context */
1989 f_pdp_ctx_act(apars);
1990
Alexander Couzens0e510e62018-07-28 23:06:00 +02001991 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001992 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1993 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1994
1995 for (i := 0; i < 5; i := i+1) {
1996 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001997 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001998 [] as_xid(apars);
1999 }
2000 }
2001
2002 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2003
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002004 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002005 setverdict(pass);
2006}
2007testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2008 var BSSGP_ConnHdlr vc_conn;
2009 f_init();
2010 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002011 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 +02002012 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002013 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002014}
2015
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002016/* ATTACH + PDP CTX ACT dropped + retrans */
2017private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2018 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2019 var Gtp1cUnitdata g_ud_first, g_ud_second;
2020 /* first perform regular attach */
2021 f_TC_attach(id);
2022
2023 /* then activate PDP context on the Gb side */
2024 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2025 apars.apn, apars.pco), 0);
2026
2027 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2028 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2029 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2030 if (g_ud_first != g_ud_second) {
2031 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2032 mtc.stop;
2033 }
2034 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2035 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2036 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2037 apars.sgsn_tei_c, apars.gtp_resp_cause,
2038 apars.ggsn_tei_c, apars.ggsn_tei_u,
2039 apars.nsapi,
2040 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2041 omit, omit));
2042 }
Harald Welte955aa942019-05-03 01:29:29 +02002043 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002044
2045 /* Now the same with Deact */
2046 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2047 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2048 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2049 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2050 if (g_ud_first != g_ud_second) {
2051 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2052 mtc.stop;
2053 }
2054 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2055 BSSGP[0].clear;
2056 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2057 }
2058 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002059 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002060 setverdict(pass);
2061 }
2062 [] as_xid(apars, 0);
2063 }
2064
2065 setverdict(pass);
2066}
2067testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2068 var BSSGP_ConnHdlr vc_conn;
2069 f_init();
2070 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2071 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002072 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002073}
2074
2075/* Test that SGSN GTP response retransmit queue works fine */
2076private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2077 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2078 var integer seq_nr := 23;
2079 var Gtp1cUnitdata g_ud_first, g_ud_second;
2080 var template Gtp1cUnitdata g_delete_req;
2081 /* first perform regular attach + PDP context act */
2082 f_TC_attach(id);
2083 f_pdp_ctx_act(apars);
2084
2085 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2086 BSSGP[0].clear;
2087 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2088 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2089 GTP.send(g_delete_req);
2090 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002091 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002092 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2093 }
2094 [] as_xid(apars, 0);
2095 }
2096 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2097 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2098 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2099 mtc.stop;
2100 }
2101 };
2102
2103 /* Send duplicate DeleteCtxReq */
2104 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2105 GTP.send(g_delete_req);
2106 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2107 if (g_ud_first != g_ud_second) {
2108 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2109 mtc.stop;
2110 }
2111 }
2112
2113 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2114 * is handled differently by SGSN (expect "non-existent" cause) */
2115 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2116 GTP.send(g_delete_req);
2117 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2118 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2119 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2120 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2121 mtc.stop;
2122 }
2123 }
2124
2125 setverdict(pass);
2126}
2127testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2128 var BSSGP_ConnHdlr vc_conn;
2129 f_init();
2130 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2131 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002132 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002133}
2134
Alexander Couzens5e307b42018-05-22 18:12:20 +02002135private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2136 /* MS: perform regular attach */
2137 f_TC_attach(id);
2138
2139 /* HLR: cancel the location request */
2140 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2141 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002142
2143 /* ensure no Detach Request got received */
2144 timer T := 5.0;
2145 T.start;
2146 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002147 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002148 T.stop;
2149 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002150 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002151 }
2152 [] T.timeout {
2153 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002154 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002155 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002156 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002157 repeat;
2158 }
2159 }
2160}
2161
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002162/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2163private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2164 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2165
2166 /* first perform regular attach */
2167 f_TC_attach(id);
2168 /* then activate PDP context */
2169 f_pdp_ctx_act(apars);
2170 /* then transceive a downlink PDU */
2171 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2172
2173 /* Send Error indication as response from upload PDU and expect deact towards MS */
2174 f_pdp_ctx_deact_mt(apars, true);
2175}
2176testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2177 var BSSGP_ConnHdlr vc_conn;
2178 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002179 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 +02002180 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002181 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002182}
2183
Alexander Couzens5e307b42018-05-22 18:12:20 +02002184testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2185 /* MS <-> SGSN: GMM Attach
2186 * HLR -> SGSN: Cancel Location Request
2187 * HLR <- SGSN: Cancel Location Ack
2188 */
2189 var BSSGP_ConnHdlr vc_conn;
2190 f_init();
2191 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002192 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002193 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002194 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002195}
2196
2197
Alexander Couzensc87967a2018-05-22 16:09:54 +02002198private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2199 /* MS: perform regular attach */
2200 f_TC_attach(id);
2201
2202 /* HLR: cancel the location request */
2203 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2204 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2205 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2206
2207 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002208 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002209 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002210
2211 setverdict(pass);
2212}
2213
2214testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2215 /* MS <-> SGSN: GMM Attach
2216 * HLR -> SGSN: Cancel Location Request
2217 * HLR <- SGSN: Cancel Location Ack
2218 * MS <- SGSN: Detach Request
2219 * SGSN-> MS: Detach Complete
2220 */
2221 var BSSGP_ConnHdlr vc_conn;
2222 f_init();
2223 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002224 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002225 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002226 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002227}
2228
2229
Alexander Couzens6c47f292018-05-22 17:09:49 +02002230private function f_hlr_location_cancel_request_unknown_subscriber(
2231 charstring id,
2232 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2233
2234 /* HLR: cancel the location request */
2235 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2236
2237 /* cause 2 = IMSI_UNKNOWN */
2238 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2239
2240 setverdict(pass);
2241}
2242
2243private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002244 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002245}
2246
2247testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2248 /* HLR -> SGSN: Cancel Location Request
2249 * HLR <- SGSN: Cancel Location Error
2250 */
2251
2252 var BSSGP_ConnHdlr vc_conn;
2253 f_init();
2254 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002255 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 +02002256 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002257 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002258}
2259
2260private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002261 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002262}
2263
2264testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2265 /* HLR -> SGSN: Cancel Location Request
2266 * HLR <- SGSN: Cancel Location Error
2267 */
2268
2269 var BSSGP_ConnHdlr vc_conn;
2270 f_init();
2271 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002272 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 +02002273 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002274 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002275}
2276
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002277private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2278 f_TC_attach(id);
2279 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2280}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002281
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002282testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2283 /* MS <-> SGSN: Attach
2284 * MS -> SGSN: Detach Req (Power off)
2285 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2286 */
2287 var BSSGP_ConnHdlr vc_conn;
2288 var integer id := 33;
2289 var charstring imsi := hex2str(f_gen_imsi(id));
2290
2291 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002292 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002293 vc_conn.done;
2294
2295 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002296 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002297}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002298
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002299/* Attempt an attach, but loose the Identification Request (IMEI) */
2300private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2301 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002302 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002303
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002304 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 +02002305
2306 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002307 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002308 /* break */
2309 }
Harald Welte955aa942019-05-03 01:29:29 +02002310 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002311 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002312 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002313 repeat;
2314 }
Harald Welte955aa942019-05-03 01:29:29 +02002315 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002316 /* ignore ID REQ IMEI */
2317 count_req := count_req + 1;
2318 repeat;
2319 }
2320 }
2321 if (count_req != 5) {
2322 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002323 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002324 }
2325 setverdict(pass);
2326}
2327
2328testcase TC_attach_no_imei_response() runs on test_CT {
2329 /* MS -> SGSN: Attach Request IMSI
2330 * MS <- SGSN: Identity Request IMSI (optional)
2331 * MS -> SGSN: Identity Response IMSI (optional)
2332 * MS <- SGSN: Identity Request IMEI
2333 * MS -x SGSN: no response
2334 * MS <- SGSN: re-send: Identity Request IMEI 4x
2335 * MS <- SGSN: Attach Reject
2336 */
2337 var BSSGP_ConnHdlr vc_conn;
2338 f_init();
2339 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002340 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 +02002341 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002342 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002343}
2344
Alexander Couzens53f20562018-06-12 16:24:12 +02002345/* Attempt an attach, but loose the Identification Request (IMSI) */
2346private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2347 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002348 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002349
2350 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2351 g_pars.p_tmsi := 'c0000035'O;
2352
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002353 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 +02002354
2355 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002356 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002357 /* break */
2358 }
Harald Welte955aa942019-05-03 01:29:29 +02002359 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002360 /* ignore ID REQ IMSI */
2361 count_req := count_req + 1;
2362 repeat;
2363 }
Harald Welte955aa942019-05-03 01:29:29 +02002364 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002365 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002366 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002367 repeat;
2368 }
2369 }
2370 if (count_req != 5) {
2371 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002372 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002373 }
2374 setverdict(pass);
2375}
2376
2377testcase TC_attach_no_imsi_response() runs on test_CT {
2378 /* MS -> SGSN: Attach Request TMSI (unknown)
2379 * MS <- SGSN: Identity Request IMEI (optional)
2380 * MS -> SGSN: Identity Response IMEI (optional)
2381 * MS <- SGSN: Identity Request IMSI
2382 * MS -x SGSN: no response
2383 * MS <- SGSN: re-send: Identity Request IMSI 4x
2384 * MS <- SGSN: Attach Reject
2385 */
2386 var BSSGP_ConnHdlr vc_conn;
2387 f_init();
2388 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002389 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 +02002390 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002391 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002392}
2393
Alexander Couzenscf818962018-06-05 18:00:00 +02002394private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2395 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2396}
2397
2398testcase TC_attach_check_subscriber_list() runs on test_CT {
2399 /* MS <-> SGSN: Attach
2400 * VTY -> SGSN: Check if MS is in subscriber cache
2401 */
2402 var BSSGP_ConnHdlr vc_conn;
2403 var integer id := 34;
2404 var charstring imsi := hex2str(f_gen_imsi(id));
2405
2406 f_init();
2407 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002408 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002409 vc_conn.done;
2410
2411 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2412 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002413 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002414}
2415
Alexander Couzensf9858652018-06-07 16:14:53 +02002416private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2417 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002418 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002419
2420 /* unregister the old IMSI */
2421 f_bssgp_client_unregister(g_pars.imsi);
2422 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002423 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002424 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002425
2426 /* there is no auth */
2427 g_pars.net.expect_auth := false;
2428
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002429 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002430 f_gmm_auth();
2431 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002432 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002433 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002434 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002435 }
Harald Welte955aa942019-05-03 01:29:29 +02002436 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2437 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002438 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002439 setverdict(pass);
2440 }
2441 }
2442}
Alexander Couzens03d12242018-08-07 16:13:52 +02002443
2444private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2445
2446 f_TC_attach_closed_foreign(id);
2447 f_TC_attach_closed_imsi_added(id);
2448
2449}
2450
2451
Alexander Couzensf9858652018-06-07 16:14:53 +02002452testcase TC_attach_closed_add_vty() runs on test_CT {
2453 /* VTY-> SGSN: policy close
2454 * MS -> SGSN: Attach Request
2455 * MS <- SGSN: Identity Request IMSI
2456 * MS -> SGSN: Identity Response IMSI
2457 * MS <- SGSN: Attach Reject
2458 * VTY-> SGSN: policy imsi-acl add IMSI
2459 * MS -> SGSN: Attach Request
2460 * MS <- SGSN: Identity Request IMSI
2461 * MS -> SGSN: Identity Response IMSI
2462 * MS <- SGSN: Identity Request IMEI
2463 * MS -> SGSN: Identity Response IMEI
2464 * MS <- SGSN: Attach Accept
2465 */
2466 var BSSGP_ConnHdlr vc_conn;
2467 f_init();
2468 f_sleep(1.0);
2469 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2470 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002471 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2472 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002473 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002474 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002475 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002476 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002477}
2478
Alexander Couzens0085bd72018-06-12 19:08:44 +02002479/* Attempt an attach, but never answer a Attach Complete */
2480private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2481 var integer count_req := 0;
2482
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002483 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 +02002484 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002485 /* Expect SGSN to perform LU with HLR */
2486 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002487
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002488 timer T := 10.0;
2489 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002490 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002491 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002492 /* break */
2493 }
Harald Welte955aa942019-05-03 01:29:29 +02002494 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002495 /* ignore */
2496 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002497 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002498 repeat;
2499 }
2500 }
2501 if (count_req != 5) {
2502 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002503 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002504 }
2505 setverdict(pass);
2506}
2507
2508testcase TC_attach_check_complete_resend() runs on test_CT {
2509 /* MS -> SGSN: Attach Request IMSI
2510 * MS <- SGSN: Identity Request *
2511 * MS -> SGSN: Identity Response *
2512 * MS <- SGSN: Attach Complete 5x
2513 */
2514 var BSSGP_ConnHdlr vc_conn;
2515 f_init();
2516 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002517 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 +02002518 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002519 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002520}
2521
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002522friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002523 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002524 var PDU_DTAP_PS_MT mt;
2525 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002526
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002527 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002528 p_tmsi := g_pars.p_tmsi;
2529 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002530 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002531 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 +02002532 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002533 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2534 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2535 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002536 setverdict(pass);
2537 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002538 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2539 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2540 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002541 setverdict(pass);
2542 }
2543
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002544 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002545 setverdict(fail, "Unexpected RAU Reject");
2546 mtc.stop;
2547 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002548 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002549 setverdict(fail, "Unexpected RAU Reject");
2550 mtc.stop;
2551 }
2552
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002553 [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 +02002554 key_sts := ?)) {
2555 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2556 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002557 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002558 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002559 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002560 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2561 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002562 }
2563}
2564
Alexander Couzensbfda9212018-07-31 03:17:33 +02002565private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002566 /* first perform regular attach */
2567 f_TC_attach(id);
2568
2569 /* then send RAU */
2570 f_routing_area_update(g_pars.ra);
2571
2572 /* do another RAU */
2573 f_routing_area_update(g_pars.ra);
2574
2575 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2576}
2577
2578testcase TC_attach_rau_a_a() runs on test_CT {
2579 /* MS <-> SGSN: Successful Attach
2580 * MS -> SGSN: Routing Area Update Request
2581 * MS <- SGSN: Routing Area Update Accept
2582 * MS -> SGSN: Routing Area Update Request
2583 * MS <- SGSN: Routing Area Update Accept
2584 * MS -> SGSN: Detach (PowerOff)
2585 */
2586 var BSSGP_ConnHdlr vc_conn;
2587 f_init();
2588 f_sleep(1.0);
2589 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2590 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002591 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002592}
2593
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002594private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002595 f_TC_attach(id);
2596
2597 log("attach complete sending rau");
2598 f_routing_area_update(g_pars.ra, 0);
2599
2600 log("rau complete unregistering");
2601 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002602 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002603
2604 log("sending second RAU via different RA");
2605 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2606
2607 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2608}
2609
2610testcase TC_attach_rau_a_b() runs on test_CT {
2611 /* MS <-> SGSN: Successful Attach
2612 * MS -> SGSN: Routing Area _a_ Update Request
2613 * MS <- SGSN: Routing Area _a_ Update Accept
2614 * MS -> SGSN: Routing Area _b_ Update Request
2615 * MS <- SGSN: Routing Area _b_ Update Accept
2616 * MS -> SGSN: Detach (PowerOff)
2617 */
2618 var BSSGP_ConnHdlr vc_conn;
2619 f_init();
2620 f_sleep(1.0);
2621 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2622 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002623 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002624}
2625
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002626private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2627 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002628 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002629 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002630 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002631
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002632 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002633
2634 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002635 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002636 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2637 mtc.stop;
2638 }
Harald Welte955aa942019-05-03 01:29:29 +02002639 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002640 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002641 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002642 repeat;
2643 }
Harald Welte955aa942019-05-03 01:29:29 +02002644 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002645 /* send out a second GMM_Attach Request.
2646 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2647 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002648 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002649 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002650 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002651 }
2652 }
2653 f_sleep(1.0);
2654
2655 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2656 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002657 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002658 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002659 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002660 repeat;
2661 }
Harald Welte955aa942019-05-03 01:29:29 +02002662 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002663 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2664 mtc.stop;
2665 }
Harald Welte955aa942019-05-03 01:29:29 +02002666 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002667 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2668 mtc.stop;
2669 }
Harald Welte955aa942019-05-03 01:29:29 +02002670 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2671 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002672 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002673 setverdict(pass);
2674 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2675 }
2676 }
2677}
2678
2679testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2680 /* Testing if the SGSN ignore Attach Request with the exact same content */
2681 /* MS -> SGSN: Attach Request IMSI
2682 * MS <- SGSN: Identity Request IMSI (optional)
2683 * MS -> SGSN: Identity Response IMSI (optional)
2684 * MS <- SGSN: Identity Request IMEI
2685 * MS -> SGSN: Attach Request (2nd)
2686 * MS <- SGSN: Identity Response IMEI
2687 * MS <- SGSN: Attach Accept
2688 * MS -> SGSN: Attach Complete
2689 */
2690 var BSSGP_ConnHdlr vc_conn;
2691 f_init();
2692 f_sleep(1.0);
2693 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2694 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2695 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002696 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002697}
2698
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002699private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002700 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2701
2702 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2703
2704 /* send Attach Request */
2705 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2706 * 3G auth vectors */
2707 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2708 /* The thing is, if the solSACapability is 'omit', then the
2709 * revisionLevelIndicatior is at the wrong place! */
2710 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002711 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002712
2713 /* do the auth */
2714 var PDU_L3_MS_SGSN l3_mo;
2715 var PDU_L3_SGSN_MS l3_mt;
2716 var default di := activate(as_mm_identity());
2717
2718 var GSUP_IE auth_tuple;
2719 var template AuthenticationParameterAUTNTLV autn;
2720
2721 g_pars.vec := f_gen_auth_vec_3g();
2722 autn := {
2723 elementIdentifier := '28'O,
2724 lengthIndicator := lengthof(g_pars.vec.autn),
2725 autnValue := g_pars.vec.autn
2726 };
2727 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2728 g_pars.vec.sres,
2729 g_pars.vec.kc,
2730 g_pars.vec.ik,
2731 g_pars.vec.ck,
2732 g_pars.vec.autn,
2733 g_pars.vec.res));
2734 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2735 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2736 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2737
2738 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2739 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002740 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002741
2742 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002743 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002744
2745 /* wait for the GSUP resync request */
2746 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2747 g_pars.imsi,
2748 g_pars.vec.auts,
2749 g_pars.vec.rand));
2750
2751 /* generate new key material */
2752 g_pars.vec := f_gen_auth_vec_3g();
2753 autn := {
2754 elementIdentifier := '28'O,
2755 lengthIndicator := lengthof(g_pars.vec.autn),
2756 autnValue := g_pars.vec.autn
2757 };
2758
2759 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2760 g_pars.vec.sres,
2761 g_pars.vec.kc,
2762 g_pars.vec.ik,
2763 g_pars.vec.ck,
2764 g_pars.vec.autn,
2765 g_pars.vec.res));
2766 /* send new key material */
2767 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2768
2769 /* wait for the new Auth Request */
2770 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2771 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002772 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002773 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2774 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2775 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2776 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2777 valueField := substr(g_pars.vec.res, 0, 4)
2778 };
2779 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2780 elementIdentifier := '21'O,
2781 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2782 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2783 };
2784 l3_mo := valueof(auth_ciph_resp);
2785 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2786 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2787 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2788 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2789 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002790 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002791 deactivate(di);
2792
2793 /* Expect SGSN to perform LU with HLR */
2794 f_gmm_gsup_lu_isd();
2795
Harald Welte955aa942019-05-03 01:29:29 +02002796 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2797 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002798 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002799 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002800 setverdict(pass);
2801}
2802
2803testcase TC_attach_usim_resync() runs on test_CT {
2804 /* MS -> SGSN: Attach Request
2805 * MS <- SGSN: Identity Request IMSI
2806 * MS -> SGSN: Identity Response IMSI
2807 * MS <- SGSN: Identity Request IMEI
2808 * MS -> SGSN: Identity Response IMEI
2809 * HLR<- SGSN: SAI Request
2810 * HLR-> SGSN: SAI Response
2811 * MS <- SGSN: Auth Request
2812 * MS -> SGSN: Auth Failure (with AUTS)
2813 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2814 * HLR-> SGSN: SAI Response (new key material)
2815 * MS <- SGSN: Auth Request (new key material)
2816 * MS -> SGSN: Auth Response
2817 * MS <- SGSN: Attach Accept
2818 * MS -> SGSN: Attach Complete
2819 */
2820 var BSSGP_ConnHdlr vc_conn;
2821 f_init();
2822 f_sleep(1.0);
2823 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2824 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002825 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002826}
2827
Harald Weltea05b8072019-04-23 22:35:05 +02002828
2829/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2830private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2831 f_gmm_attach(false, false);
2832 f_sleep(1.0);
2833 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2834 /* try to detach to check if SGSN is still alive */
2835 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2836}
2837testcase TC_llc_null() runs on test_CT {
2838 var BSSGP_ConnHdlr vc_conn;
2839 f_init();
2840 f_sleep(1.0);
2841 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2842 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002843 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002844}
2845
Harald Welte645a1512019-04-23 23:18:23 +02002846/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2847private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2848 f_gmm_attach(false, false);
2849 f_sleep(1.0);
2850 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002851 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002852 setverdict(pass);
2853}
2854testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2855 var BSSGP_ConnHdlr vc_conn;
2856 f_init();
2857 f_sleep(1.0);
2858 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2859 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002860 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002861}
2862
2863/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2864private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2865 f_gmm_attach(false, false);
2866 f_sleep(1.0);
2867 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002868 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002869 setverdict(pass);
2870}
2871testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2872 var BSSGP_ConnHdlr vc_conn;
2873 f_init();
2874 f_sleep(1.0);
2875 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2876 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002877 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002878}
2879
Harald Welte2aaac1b2019-05-02 10:02:53 +02002880/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2881private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2882 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2883 var template (value) XID_Information xid;
2884 var template XID_Information xid_rx;
2885
2886 /* first perform regular attach */
2887 f_TC_attach(id);
2888 /* then activate PDP context */
2889 f_pdp_ctx_act(apars);
2890
2891 /* start MO XID */
2892 xid := { ts_XID_L3(''O) };
2893 xid_rx := { tr_XID_L3(''O) };
2894 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2895 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002896 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002897 [] as_xid(apars);
2898 }
2899 setverdict(pass);
2900}
2901testcase TC_xid_empty_l3() runs on test_CT {
2902 var BSSGP_ConnHdlr vc_conn;
2903 f_init();
2904 f_sleep(1.0);
2905 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2906 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002907 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002908}
2909
2910private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2911 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2912 var template (value) XID_Information xid;
2913 var template XID_Information xid_rx;
2914
2915 /* first perform regular attach */
2916 f_TC_attach(id);
2917 /* then activate PDP context */
2918 f_pdp_ctx_act(apars);
2919
2920 /* start MO XID */
2921 xid := { ts_XID_N201U(1234) };
2922 xid_rx := { tr_XID_N201U(1234) };
2923 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2924 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002925 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002926 [] as_xid(apars);
2927 }
2928 setverdict(pass);
2929}
2930testcase TC_xid_n201u() runs on test_CT {
2931 var BSSGP_ConnHdlr vc_conn;
2932 f_init();
2933 f_sleep(1.0);
2934 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2935 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002936 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002937}
2938
Alexander Couzens6bee0872019-05-11 01:48:50 +02002939private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2940 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2941
2942 /* first perform regular attach */
2943 f_TC_attach(id);
2944 /* then activate PDP context */
2945 f_pdp_ctx_act(apars);
2946 /* do a normal detach */
2947 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2948}
2949
2950testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2951 /* MS -> SGSN: Attach Request
2952 * MS <-> SGSN: [..]
2953 * MS -> SGSN: Attach Complete
2954 * MS -> SGSN: PDP Activate Request
2955 * MS <- SGSN: PDP Activate Accept
2956 * MS -> SGSN: GMM Detach Request
2957 * MS <- SGSN: GMM Detach Accept
2958 */
2959 var BSSGP_ConnHdlr vc_conn;
2960 f_init();
2961 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2962 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002963 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002964}
Harald Welte645a1512019-04-23 23:18:23 +02002965
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002966private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2967 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2968 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2969 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2970 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2971 var PDU_L3_SGSN_MS l3_mt;
2972
2973 f_send_l3(attach_req, 0);
2974
2975 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2976
2977 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2978 alt {
2979 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2980 setverdict(pass);
2981 }
2982 [] BSSGP[0].receive { repeat; }
2983 }
2984}
2985
2986/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2987 * See OS#3957 and OS#4245 for more information.
2988 */
2989testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2990 /*
2991 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2992 * MS <-- SGSN: Identity Request (IMEI)
2993 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2994 */
2995 var BSSGP_ConnHdlr vc_conn;
2996 f_init();
2997 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2998 vc_conn.done;
2999 f_cleanup();
3000}
3001
Harald Welte8e5932e2020-06-17 22:12:54 +02003002private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3003var PDU_BSSGP rx;
3004[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3005 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3006 mtc.stop;
3007 }
3008}
3009
3010/* SUSPEND, then DL traffic: should not pass + no paging expected */
3011private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3012 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3013 var default d;
3014
3015 /* first perform regular attach */
3016 f_TC_attach(id);
3017 /* then activate PDP context */
3018 f_pdp_ctx_act(apars);
3019 /* then transceive a downlink PDU */
3020 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3021
3022 /* now suspend GPRS */
3023 f_bssgp_suspend();
3024
3025 d := activate(as_nopaging_ps());
3026
3027 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3028 * nor any related paging requests */
3029 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3030
3031 deactivate(d);
3032}
3033testcase TC_suspend_nopaging() runs on test_CT {
3034 var BSSGP_ConnHdlr vc_conn;
3035 f_init();
3036 f_sleep(1.0);
3037 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3038 vc_conn.done;
3039 f_cleanup();
3040}
3041
3042
3043/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3044private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3045 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3046 var OCT1 susp_ref;
3047 var default d;
3048
3049 /* first perform regular attach */
3050 f_TC_attach(id);
3051 /* then activate PDP context */
3052 f_pdp_ctx_act(apars);
3053 /* then transceive a downlink PDU */
3054 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3055
3056 /* now suspend GPRS */
3057 susp_ref := f_bssgp_suspend();
3058
3059 d := activate(as_nopaging_ps());
3060
3061 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3062 * nor any related paging requests */
3063 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3064
3065 deactivate(d);
3066
3067 /* resume GPRS */
3068 f_bssgp_resume(susp_ref);
3069
3070 /* now data should be flowing again */
3071 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3072}
3073testcase TC_suspend_resume() runs on test_CT {
3074 var BSSGP_ConnHdlr vc_conn;
3075 f_init();
3076 f_sleep(1.0);
3077 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3078 vc_conn.done;
3079 f_cleanup();
3080}
3081
3082/* SUSPEND, then RAU: data expected to flow after implicit resume */
3083private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3084 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3085 var default d;
3086
3087 /* first perform regular attach */
3088 f_TC_attach(id);
3089 /* then activate PDP context */
3090 f_pdp_ctx_act(apars);
3091 /* then transceive a downlink PDU */
3092 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3093
3094 /* now suspend GPRS */
3095 f_bssgp_suspend();
3096
3097 d := activate(as_nopaging_ps());
3098
3099 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3100 * nor any related paging requests */
3101 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3102
3103 deactivate(d);
3104
3105 /* perform RAU (implicit RESUME) */
3106 f_routing_area_update(g_pars.ra);
3107
Harald Welted5836dc2021-03-20 15:40:00 +01003108 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3109 f_sleep(0.5);
3110
Harald Welte8e5932e2020-06-17 22:12:54 +02003111 /* now data should be flowing again */
3112 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3113
3114}
3115testcase TC_suspend_rau() runs on test_CT {
3116 var BSSGP_ConnHdlr vc_conn;
3117 f_init();
3118 f_sleep(1.0);
3119 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3120 vc_conn.done;
3121 f_cleanup();
3122}
3123
3124
3125/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3126private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3127 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3128 var default d;
3129
3130 /* first perform regular attach */
3131 f_TC_attach(id);
3132 /* then activate PDP context */
3133 f_pdp_ctx_act(apars);
3134 /* then transceive a downlink PDU */
3135 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3136
3137 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3138 f_sleep(5.0);
3139
3140 /* now data should be flowing again, but with PS PAGING */
3141 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3142 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3143
3144 /* FIXME: simulate paging response */
3145 /* FIXME: verify PDU actually arrives only after paging response was successful */
3146
3147}
3148testcase TC_paging_ps() runs on test_CT {
3149 var BSSGP_ConnHdlr vc_conn;
3150 f_init();
3151 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3152 f_sleep(1.0);
3153 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3154 vc_conn.done;
3155 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3156 f_cleanup();
3157}
3158
Philipp Maier7df55e02020-12-14 23:46:04 +01003159private function f_TC_bssgp_rim_dummy(charstring id) runs on BSSGP_ConnHdlr {
3160}
3161
3162/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3163 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3164 * other and vice versa. */
3165testcase TC_bssgp_rim_single_report() runs on test_CT {
3166 var BSSGP_ConnHdlr vc_conn;
3167 f_init();
3168 vc_conn := f_start_handler(refers(f_TC_bssgp_rim_dummy), testcasename(), g_gb, 17);
3169 vc_conn.done;
3170
3171 timer T := 2.0;
3172
3173 var template RIM_Routing_Address dst_addr;
3174 var template RIM_Routing_Address src_addr;
3175 var template RAN_Information_Request_RIM_Container req_cont;
3176 var template RAN_Information_RIM_Container res_cont;
3177 var template PDU_BSSGP bssgp_rim_pdu;
3178 var template PDU_BSSGP bssgp_rim_pdu_expect;
3179
3180 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3181 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003182
3183
Philipp Maier7df55e02020-12-14 23:46:04 +01003184 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3185 * based on the cell id in dst_addr to GB interface #1. */
3186 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3187 ts_RIM_Sequence_Number(1),
3188 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3189 ts_RIM_Protocol_Version_Number(1),
3190 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3191 omit);
3192 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3193 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3194 req_cont);
3195 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3196 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3197 tr_RAN_Information_Request_RIM_Container);
3198 RIM[0].send(bssgp_rim_pdu);
3199 T.start;
3200 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003201 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3202 setverdict(pass);
3203 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003204 [] RIM[1].receive {
3205 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003206 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003207 [] T.timeout {
3208 setverdict(fail, "No BSSGP RIM PDU received");
3209 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003210 }
3211 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003212
Philipp Maier7df55e02020-12-14 23:46:04 +01003213 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3214 * GB interface #0 */
3215 var octetstring si1 := '198fb100000000000000000000000000007900002b'O;
3216 var octetstring si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
3217 var octetstring si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
3218 var octetstring si := si1 & si3 & si13;
3219
3220 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3221 ts_RIM_Sequence_Number(2),
3222 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3223 ts_RIM_Protocol_Version_Number(1),
3224 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si)),
3225 omit);
3226 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3227 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3228 res_cont);
3229 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3230 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3231 ?);
3232 RIM[1].send(bssgp_rim_pdu);
3233 T.start;
3234 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003235 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3236 setverdict(pass);
3237 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003238 [] RIM[0].receive {
3239 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003240 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003241 [] T.timeout {
3242 setverdict(fail, "No BSSGP RIM PDU received");
3243 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003244 }
3245 }
3246
3247 f_cleanup();
3248}
Harald Welte8e5932e2020-06-17 22:12:54 +02003249
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003250/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3251private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3252 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3253
3254 /* first perform regular attach */
3255 f_gmm_attach(false, false, ran_index := 0);
3256 /* then activate PDP context */
3257 f_pdp_ctx_act(apars, ran_index := 0);
3258 /* then transceive a downlink PDU */
3259 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3260 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3261
3262 /* Now attach on different cell: */
3263 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3264 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3265 g_pars.net.expect_auth := false;
3266 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3267 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3268 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3269}
3270testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3271 var BSSGP_ConnHdlr vc_conn;
3272 f_init();
3273 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3274 vc_conn.done;
3275 f_cleanup();
3276}
3277
3278/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3279/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3280private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3281 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3282
3283 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3284 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3285
3286 /* first perform regular attach */
3287 f_gmm_attach(false, false, ran_index := 1);
3288 /* then activate PDP context */
3289 f_pdp_ctx_act(apars, ran_index := 1);
3290 /* then transceive a downlink PDU */
3291 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3292 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3293
3294 /* Now attach on different cell: */
3295 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3296 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3297 g_pars.net.expect_auth := false;
3298 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3299 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3300 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3301}
3302testcase TC_cell_change_different_ci_attach() runs on test_CT {
3303 var BSSGP_ConnHdlr vc_conn;
3304 f_init();
3305 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3306 vc_conn.done;
3307 f_cleanup();
3308}
3309
3310/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3311private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3312 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3313
3314 /* first perform regular attach */
3315 f_gmm_attach(false, false, ran_index := 0);
3316 /* then activate PDP context */
3317 f_pdp_ctx_act(apars, ran_index := 0);
3318 /* then transceive a downlink PDU */
3319 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3320 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3321
3322 /* Send some data over new bvci, it should be silently discarded since
3323 * RAC changed and SGSN expects a RAU to occur in that case */
3324 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3325 var octetstring payload := f_rnd_octstring(200);
3326 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3327 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
3328 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
3329 timer T := 2.0;
3330 T.start;
3331 alt {
3332 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3333 setverdict(fail, "Unexpected GTP message");
3334 }
3335 [] T.timeout { setverdict(pass); }
3336 }
3337
3338 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3339 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3340 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3341}
3342testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3343 var BSSGP_ConnHdlr vc_conn;
3344 f_init();
3345 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3346 vc_conn.done;
3347 f_cleanup();
3348}
3349
3350/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3351/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3352private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3353 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3354
3355 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3356 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3357
3358 /* first perform regular attach */
3359 f_gmm_attach(false, false, ran_index := 1);
3360 /* then activate PDP context */
3361 f_pdp_ctx_act(apars, ran_index := 1);
3362 /* then transceive a downlink PDU */
3363 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3364 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3365
3366 /* Now attach on different cell: */
3367 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3368 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3369
3370 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3371 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3372}
3373testcase TC_cell_change_different_ci_data() runs on test_CT {
3374 var BSSGP_ConnHdlr vc_conn;
3375 f_init();
3376 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3377 vc_conn.done;
3378 f_cleanup();
3379}
3380
Harald Welte5ac31492018-02-15 20:39:13 +01003381control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003382 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003383 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003384 execute( TC_attach_umts_aka_umts_res() );
3385 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003386 execute( TC_attach_auth_id_timeout() );
3387 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003388 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003389 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003390 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003391 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003392 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003393 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003394 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003395 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003396 execute( TC_attach_closed_add_vty(), 20.0 );
3397 execute( TC_attach_check_subscriber_list(), 20.0 );
3398 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003399 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003400 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3401 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3402 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3403 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003404 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003405 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003406 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003407 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003408 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003409 execute( TC_detach_unknown_nopoweroff() );
3410 execute( TC_detach_unknown_poweroff() );
3411 execute( TC_detach_nopoweroff() );
3412 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003413 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003414 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003415 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003416 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003417 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003418 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003419 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003420 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003421 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003422 execute( TC_attach_restart_ctr_echo() );
3423 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003424 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003425 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3426 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003427 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003428 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003429 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003430
Harald Welte2aaac1b2019-05-02 10:02:53 +02003431 execute( TC_xid_empty_l3() );
3432 execute( TC_xid_n201u() );
3433
Harald Weltea05b8072019-04-23 22:35:05 +02003434 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003435 execute( TC_llc_sabm_dm_llgmm() );
3436 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003437
Harald Welte8e5932e2020-06-17 22:12:54 +02003438 execute( TC_suspend_nopaging() );
3439 execute( TC_suspend_resume() );
3440 execute( TC_suspend_rau() );
3441 execute( TC_paging_ps() );
3442
Philipp Maier7df55e02020-12-14 23:46:04 +01003443 execute( TC_bssgp_rim_single_report() );
3444
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003445 execute( TC_cell_change_different_rai_ci_attach() );
3446 execute( TC_cell_change_different_rai_ci_data() );
3447 execute( TC_cell_change_different_ci_attach() );
3448 execute( TC_cell_change_different_ci_data() );
3449
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003450 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3451 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003452}
Harald Welte96a33b02018-02-04 10:36:22 +01003453
3454
3455
3456}