blob: d760e58219ca83024b8f5c48f6368737ad6416e0 [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;
Pau Espin Pedrol7bac69f2021-05-04 15:53:06 +020067 charstring mp_ggsn_ip := "127.0.0.103";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +020069 charstring mp_sgsn_gtp_ip := "127.0.0.10";
Alexander Couzens2c12b242018-07-31 00:30:11 +020070
Alexander Couzensf3c1b412018-08-24 00:42:51 +020071 NSConfigurations mp_nsconfig := {
72 {
Harald Welte5e514fa2018-07-05 00:01:45 +020073 nsei := 96,
74 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010075 handle_sns := false,
76 nsvc := {
77 {
78 provider := {
79 ip := {
80 address_family := AF_INET,
81 local_udp_port := 21010,
82 local_ip := "127.0.0.1",
83 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +010084 remote_ip := "127.0.0.1",
85 data_weight := 1,
86 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +010087 }
88 },
89 nsvci := 97
90 }
91 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020092 },
93 {
Harald Welte5e514fa2018-07-05 00:01:45 +020094 nsei := 97,
95 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010096 handle_sns := false,
97 nsvc := {
98 {
99 provider := {
100 ip := {
101 address_family := AF_INET,
102 local_udp_port := 21011,
103 local_ip := "127.0.0.1",
104 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100105 remote_ip := "127.0.0.1",
106 data_weight := 1,
107 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100108 }
109 },
110 nsvci := 98
111 }
112 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200113 },
114 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200115 nsei := 98,
116 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100117 handle_sns := false,
118 nsvc := {
119 {
120 provider := {
121 ip := {
122 address_family := AF_INET,
123 local_udp_port := 21012,
124 local_ip := "127.0.0.1",
125 remote_udp_port := 23000,
Harald Weltebe7afce2021-01-17 22:04:36 +0100126 remote_ip := "127.0.0.1",
127 data_weight := 1,
128 signalling_weight := 1
Harald Welte90f19742020-11-06 19:34:40 +0100129 }
130 },
131 nsvci := 99
132 }
133 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200134 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200135 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200136
137 RAN_Configurations mp_ranap_cfg := {
138 {
139 transport := RANAP_TRANSPORT_IuCS,
140 sccp_service_type := "mtp3_itu",
141 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
142 own_pc := 195,
143 own_ssn := 142,
144 peer_pc := 188, /* 0.23.4 */
145 peer_ssn := 142,
146 sio := '83'O,
147 rctx := 2
148 }
149 }
Harald Welte5ac31492018-02-15 20:39:13 +0100150};
151
Harald Welte5339b2e2020-10-04 22:52:56 +0200152const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100153type record GbInstance {
154 NS_CT vc_NS,
155 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200156 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100157 BssgpConfig cfg
158};
Harald Welte96a33b02018-02-04 10:36:22 +0100159
Harald Welte2fa771f2019-05-02 20:13:53 +0200160const integer NUM_GB := 3;
161type record length(NUM_GB) of GbInstance GbInstances;
162type record length(NUM_GB) of NSConfiguration NSConfigurations;
163type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200164
Harald Welte26fbb6e2019-04-14 17:32:46 +0200165const integer NUM_RNC := 1;
166type record of RAN_Configuration RAN_Configurations;
167
Harald Welte96a33b02018-02-04 10:36:22 +0100168type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200169 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200170 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200171 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100172
Harald Welte5ac31492018-02-15 20:39:13 +0100173 var GSUP_Emulation_CT vc_GSUP;
174 var IPA_Emulation_CT vc_GSUP_IPA;
175 /* only to get events from IPA underneath GSUP */
176 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100177
Harald Welte5339b2e2020-10-04 22:52:56 +0200178 /* only needed at start to get the per-BVC references */
179 port BSSGP_CT_PROC_PT PROC;
180
Philipp Maier7df55e02020-12-14 23:46:04 +0100181 /* used by RIM related test */
182 port BSSGP_PT RIM[NUM_GB];
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200183 port GTPEM_PT GTPC;
Philipp Maier7df55e02020-12-14 23:46:04 +0100184
Harald Welteeded9ad2018-02-17 20:57:34 +0100185 var GTP_Emulation_CT vc_GTP;
186
Harald Weltebd194722018-02-16 22:11:08 +0100187 port TELNETasp_PT SGSNVTY;
188
Harald Welte96a33b02018-02-04 10:36:22 +0100189 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200190 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100191};
192
Harald Welte26fbb6e2019-04-14 17:32:46 +0200193type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100194 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100195 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200196 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100197}
198
199type record SGSN_ConnHdlrNetworkPars {
200 boolean expect_ptmsi,
201 boolean expect_auth,
202 boolean expect_ciph
203};
204
205type record BSSGP_ConnHdlrPars {
206 /* IMEI of the simulated ME */
207 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200208 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100209 hexstring imsi,
210 /* MSISDN of the simulated MS (probably unused) */
211 hexstring msisdn,
212 /* P-TMSI allocated to the simulated MS */
213 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100214 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100215 /* TLLI of the simulated MS */
216 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100217 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100218 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200219 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200220 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
221 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100222 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100223 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200224 float t_guard,
225 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200226 SCCP_PAR_Address sccp_addr_local optional,
227 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100228};
229
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +0200230/* Passed in RAN-INFO message from emulated neighbor using RIM */
231const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
232const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
233const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
234const octetstring si_default := si1_default & si3_default & si13_default;
235
Alexander Couzens89508702018-07-31 04:16:10 +0200236private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200237 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200238 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
239
240 var RoutingAreaIdentificationV ret := {
241 mccDigit1 := mcc_mnc[0],
242 mccDigit2 := mcc_mnc[1],
243 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200244 mncDigit3 := mcc_mnc[3],
245 mncDigit1 := mcc_mnc[4],
246 mncDigit2 := mcc_mnc[5],
Pau Espin Pedroldeaaa902021-02-12 18:41:04 +0100247 lac := int2oct(cell_id.ra_id.lai.lac, 2),
248 rac := int2oct(cell_id.ra_id.rac, 1)
Alexander Couzens89508702018-07-31 04:16:10 +0200249 }
250 return ret;
251};
252
Alexander Couzens51114d12018-07-31 18:41:56 +0200253private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
254 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
255 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100256 /* connect lower end of BSSGP emulation with NS upper port */
257 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100258
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200259 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200260 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
261 /* resolve the per-BVC component references */
262 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
263 connect(self:PROC, gb.vc_BSSGP:PROC);
264 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
265 disconnect(self:PROC, gb.vc_BSSGP:PROC);
266 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100267 /* connect RIM related port */
268 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100269}
270
271private function f_init_gsup(charstring id) runs on test_CT {
272 id := id & "-GSUP";
273 var GsupOps ops := {
274 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
275 };
276
277 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
278 vc_GSUP := GSUP_Emulation_CT.create(id);
279
280 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
281 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
282 /* we use this hack to get events like ASP_IPA_EVENT_UP */
283 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
284
285 vc_GSUP.start(GSUP_Emulation.main(ops, id));
286 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
287
288 /* wait for incoming connection to GSUP port before proceeding */
289 timer T := 10.0;
290 T.start;
291 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700292 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100293 [] T.timeout {
294 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200295 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100296 }
297 }
298}
299
Harald Welteeded9ad2018-02-17 20:57:34 +0100300private function f_init_gtp(charstring id) runs on test_CT {
301 id := id & "-GTP";
302
303 var GtpEmulationCfg gtp_cfg := {
304 gtpc_bind_ip := mp_ggsn_ip,
305 gtpc_bind_port := GTP1C_PORT,
306 gtpu_bind_ip := mp_ggsn_ip,
307 gtpu_bind_port := GTP1U_PORT,
308 sgsn_role := false
309 };
310
311 vc_GTP := GTP_Emulation_CT.create(id);
312 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
313}
314
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200315friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100316 map(self:SGSNVTY, system:SGSNVTY);
317 f_vty_set_prompts(SGSNVTY);
318 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200319 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100320 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
321}
322
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200323private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
324 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200325 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200326 } else {
327 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
328 }
329}
330
Harald Weltebd194722018-02-16 22:11:08 +0100331
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200332/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
333function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200334 var integer i;
335
Harald Welte96a33b02018-02-04 10:36:22 +0100336 if (g_initialized == true) {
337 return;
338 }
339 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100340 g_gb[0].cfg := {
341 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200342 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200343 bvc := {
344 {
345 bvci := 196,
346 cell_id := {
347 ra_id := {
348 lai := {
349 mcc_mnc := mcc_mnc,
350 lac := 13135
351 },
352 rac := 0
353 },
354 cell_id := 20960
355 },
Harald Welte4d112c92020-11-12 19:48:31 +0100356 depth := BSSGP_DECODE_DEPTH_L3,
357 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200358 }
359 }
Harald Welte5ac31492018-02-15 20:39:13 +0100360 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200361 g_gb[1].cfg := {
362 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200363 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200364 bvc := {
365 {
366 bvci := 210,
367 cell_id := {
368 ra_id := {
369 lai := {
370 mcc_mnc := mcc_mnc,
371 lac := 13200
372 },
373 rac := 0
374 },
375 cell_id := 20961
376 },
Harald Welte4d112c92020-11-12 19:48:31 +0100377 depth := BSSGP_DECODE_DEPTH_L3,
378 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200379 }
380 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200381 };
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100382 g_gb[2].cfg := { /* [2] configured to have same RAC as [1] */
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200383 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200384 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200385 bvc := {
386 {
387 bvci := 220,
388 cell_id := {
389 ra_id := {
390 lai := {
391 mcc_mnc := mcc_mnc,
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100392 lac := 13200
Harald Welte5339b2e2020-10-04 22:52:56 +0200393 },
394 rac := 0
395 },
396 cell_id := 20962
397 },
Harald Welte4d112c92020-11-12 19:48:31 +0100398 depth := BSSGP_DECODE_DEPTH_L3,
399 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200400 }
401 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200402 };
Harald Welte96a33b02018-02-04 10:36:22 +0100403
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200404 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200405 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
406 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
407 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200408
Alexander Couzens1552e792019-07-23 20:38:39 +0200409 if (g_ranap_enable) {
410 for (i := 0; i < NUM_RNC; i := i+1) {
411 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
412 f_ran_adapter_start(g_ranap[i]);
413 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200414 }
Harald Welte5ac31492018-02-15 20:39:13 +0100415 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100416 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200417 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100418}
Harald Welte96a33b02018-02-04 10:36:22 +0100419
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200420function f_cleanup() runs on test_CT {
421 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200422 if (g_ranap_enable) {
423 for (i := 0; i < NUM_RNC; i := i+1) {
424 f_ran_adapter_cleanup(g_ranap[i]);
425 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200426 }
427 self.stop;
428}
429
Harald Welte26fbb6e2019-04-14 17:32:46 +0200430private function RncUnitdataCallback(RANAP_PDU ranap)
431runs on RAN_Emulation_CT return template RANAP_PDU {
432 var template RANAP_PDU resp := omit;
433
434 log ("RANAP_RncUnitDataCallback");
435 /* answer all RESET with RESET ACK */
436 if (match(ranap, tr_RANAP_Reset)) {
437 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
438 var CN_DomainIndicator dom;
439 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
440 resp := ts_RANAP_ResetAck(dom);
441 }
442 return resp;
443}
444
445const RanOps RNC_RanOps := {
446 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
447 ranap_unitdata_cb := refers(RncUnitdataCallback),
448 ps_domain := true,
449 decode_dtap := true,
450 role_ms := true,
451 protocol := RAN_PROTOCOL_RANAP,
452 transport := RANAP_TRANSPORT_IuCS,
453 use_osmux := false,
454 sccp_addr_local := omit,
455 sccp_addr_peer := omit
456};
457
Harald Welte5ac31492018-02-15 20:39:13 +0100458type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
459
460/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200461function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100462 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100463runs on test_CT return BSSGP_ConnHdlr {
464 var BSSGP_ConnHdlr vc_conn;
465 var SGSN_ConnHdlrNetworkPars net_pars := {
466 expect_ptmsi := true,
467 expect_auth := true,
468 expect_ciph := false
469 };
470 var BSSGP_ConnHdlrPars pars := {
471 imei := f_gen_imei(imsi_suffix),
472 imsi := f_gen_imsi(imsi_suffix),
473 msisdn := f_gen_msisdn(imsi_suffix),
474 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100475 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100476 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100477 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100478 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200479 bssgp_cell_id := {
480 gb[0].cfg.bvc[0].cell_id,
481 gb[1].cfg.bvc[0].cell_id,
482 gb[2].cfg.bvc[0].cell_id
483 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200484 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100485 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100486 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200487 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200488 sccp_addr_local := omit,
489 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100490 };
491
Alexander Couzens1552e792019-07-23 20:38:39 +0200492 if (g_ranap_enable) {
493 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
494 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
495 }
496
Harald Welte5ac31492018-02-15 20:39:13 +0100497 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200498
499 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
500 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
501 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100502 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200503
504 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
505 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
506 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100507 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200508
509 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
510 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
511 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100512 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100513
Harald Welte26fbb6e2019-04-14 17:32:46 +0200514 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200515 if (g_ranap_enable) {
516 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
517 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
518 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200519
Harald Welte5ac31492018-02-15 20:39:13 +0100520 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
521 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
522
Harald Welteeded9ad2018-02-17 20:57:34 +0100523 connect(vc_conn:GTP, vc_GTP:CLIENT);
524 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
525
Harald Welte5ac31492018-02-15 20:39:13 +0100526 vc_conn.start(f_handler_init(fn, id, pars));
527 return vc_conn;
528}
529
Harald Welte62e29582018-02-16 21:17:11 +0100530private altstep as_Tguard() runs on BSSGP_ConnHdlr {
531 [] g_Tguard.timeout {
532 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200533 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100534 }
535}
536
Harald Welte5ac31492018-02-15 20:39:13 +0100537/* first function called in every ConnHdlr */
538private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
539runs on BSSGP_ConnHdlr {
540 /* do some common stuff like setting up g_pars */
541 g_pars := pars;
542
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200543 llc := f_llc_create(false);
544
Harald Welte5ac31492018-02-15 20:39:13 +0100545 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200546 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100547 /* tell GSUP dispatcher to send this IMSI to us */
548 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100549 /* tell GTP dispatcher to send this IMSI to us */
550 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100551
Harald Welte62e29582018-02-16 21:17:11 +0100552 g_Tguard.start(pars.t_guard);
553 activate(as_Tguard());
554
Harald Welte5ac31492018-02-15 20:39:13 +0100555 /* call the user-supplied test case function */
556 fn.apply(id);
557 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100558}
559
560/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100561 * Detach without Attach
562 * SM procedures without attach / RAU
563 * ATTACH / RAU
564 ** with / without authentication
565 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100566 * re-transmissions of LLC frames
567 * PDP Context activation
568 ** with different GGSN config in SGSN VTY
569 ** with different PDP context type (v4/v6/v46)
570 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100571 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100572 */
573
574testcase TC_wait_ns_up() runs on test_CT {
575 f_init();
576 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200577 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100578}
579
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200580friend function is_gb(integer ran_index) return boolean {
581 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200582}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200583friend function is_iu(integer ran_index) return boolean {
584 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200585}
586
Alexander Couzens0507ec32019-09-15 22:41:22 +0200587function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200588 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200589 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 +0200590}
591
Alexander Couzens0507ec32019-09-15 22:41:22 +0200592private 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 +0200593 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
594 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
595 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200596 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200597}
598
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200599/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
600function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
601 log("Sending InitialUE: ", l3_mo);
602 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
603 var RANAP_PDU ranap;
604 var LAI lai := {
605 pLMNidentity := '62F224'O,
606 lAC := '1234'O,
607 iE_Extensions := omit
608 };
609 var SAI sai := {
610 pLMNidentity := lai.pLMNidentity,
611 lAC := lai.lAC,
612 sAC := '0000'O, /* FIXME */
613 iE_Extensions := omit
614 };
615 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
616 var GlobalRNC_ID grnc_id := {
617 pLMNidentity := lai.pLMNidentity,
618 rNC_ID := 2342 /* FIXME */
619 };
620
621 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
622 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
623 alt {
624 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
625 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
626 setverdict(fail, "DISC.ind from SCCP");
627 mtc.stop;
628 }
629 }
630}
631
632/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200633function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
634 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200635 if (g_pars.rnc_send_initial_ue) {
636 g_pars.rnc_send_initial_ue := false;
637 f_send_l3_initial_ue(l3_mo);
638 } else {
639 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
640 }
641 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200642 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200643 }
644}
645
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200646altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700647 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200648 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100649 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200650 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100651 repeat;
652 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200653 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200654 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200655 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200656 repeat;
657 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200658 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100659 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200660 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200661 repeat;
662 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200663 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200664 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200665 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100666 repeat;
667 }
668}
Harald Welte96a33b02018-02-04 10:36:22 +0100669
Harald Welteca362462019-05-02 20:11:21 +0200670/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200671function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200672runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200673 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200674 var PDU_L3_SGSN_MS l3_mt;
675 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200676 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
677 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200678 l3_mt := mt.dtap;
679 }
Harald Welteca362462019-05-02 20:11:21 +0200680 }
681 return l3_mt;
682}
683
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200684/* perform GMM authentication (if expected).
685 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
686 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200687function 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 +0100688 var PDU_L3_MS_SGSN l3_mo;
689 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200690 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100691 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200692 var GSUP_IE auth_tuple;
693 var template AuthenticationParameterAUTNTLV autn;
694
695 if (umts_aka_challenge) {
696 g_pars.vec := f_gen_auth_vec_3g();
697 autn := {
698 elementIdentifier := '28'O,
699 lengthIndicator := lengthof(g_pars.vec.autn),
700 autnValue := g_pars.vec.autn
701 };
702
703 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
704 g_pars.vec.sres,
705 g_pars.vec.kc,
706 g_pars.vec.ik,
707 g_pars.vec.ck,
708 g_pars.vec.autn,
709 g_pars.vec.res));
710 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
711 } else {
712 g_pars.vec := f_gen_auth_vec_2g();
713 autn := omit;
714 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
715 g_pars.vec.sres,
716 g_pars.vec.kc));
717 log("GSUP sends only 2G auth tuple", auth_tuple);
718 }
Harald Welteca362462019-05-02 20:11:21 +0200719
Harald Welte5ac31492018-02-15 20:39:13 +0100720 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
721 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200722
723 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
724 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200725 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100726 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200727 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
728
729 if (umts_aka_challenge and not force_gsm_sres) {
730 /* set UMTS response instead */
731 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
732 valueField := substr(g_pars.vec.res, 0, 4)
733 };
734 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
735 elementIdentifier := '21'O,
736 lengthIndicator := lengthof(g_pars.vec.res) - 4,
737 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
738 };
739 }
740
741 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100742 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
743 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
744 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
745 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
746 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200747 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200748
749 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200750 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200751 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
752 key_sts := ?)) {
753 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
754 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200755 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200756 }
757 }
Harald Welte76dee092018-02-16 22:12:59 +0100758 } else {
759 /* wait for identity procedure */
760 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100761 }
Harald Welte76dee092018-02-16 22:12:59 +0100762
Harald Welte5ac31492018-02-15 20:39:13 +0100763 deactivate(di);
764}
765
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200766function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100767 g_pars.p_tmsi := p_tmsi;
768 /* update TLLI */
769 g_pars.tlli_old := g_pars.tlli;
770 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100771 if (is_gb(ran_index)) {
772 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
773 }
Harald Weltef70997d2018-02-17 10:11:19 +0100774}
775
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100776function f_process_attach_accept(PDU_GMM_AttachAccept aa, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +0100777 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100778 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Harald Weltedd9fb842021-02-16 20:21:22 +0100779 /* we cannot use ran_index here, as it would overflow the cell_id object, since ran_idx > NUM_GB
780 * indicates an Iu RAN connection. All cells are expected to run the same MCC/MNC anyway... */
781 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100782 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100783 & "; expected " & hex2str(g_pars.bssgp_cell_id[ran_index].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200784 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100785 }
Harald Welte04683d02018-02-16 22:43:45 +0100786 g_pars.ra := aa.routingAreaIdentification;
787 if (ispresent(aa.allocatedPTMSI)) {
788 if (not g_pars.net.expect_ptmsi) {
789 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200790 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100791 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100792 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
793 ran_index);
Harald Welte04683d02018-02-16 22:43:45 +0100794 }
795 if (ispresent(aa.msIdentity)) {
796 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200797 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100798 }
799 /* P-TMSI.sig */
800 if (ispresent(aa.ptmsiSignature)) {
801 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
802 }
803 /* updateTimer */
804 // aa.readyTimer
805 /* T3302, T3319, T3323, T3312_ext, T3324 */
806}
807
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200808function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100809 /* mandatory IE */
810 g_pars.ra := ra.routingAreaId;
811 if (ispresent(ra.allocatedPTMSI)) {
812 if (not g_pars.net.expect_ptmsi) {
813 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200814 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100815 }
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100816 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets,
817 ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100818 }
819 if (ispresent(ra.msIdentity)) {
820 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200821 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100822 }
823 /* P-TMSI.sig */
824 if (ispresent(ra.ptmsiSignature)) {
825 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
826 }
827 /* updateTimer */
828 // aa.readyTimer
829 /* T3302, T3319, T3323, T3312_ext, T3324 */
830}
831
832
Harald Welte5a4fa042018-02-16 20:59:21 +0100833function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
834 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
835}
836
Harald Welte23178c52018-02-17 09:36:33 +0100837/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700838private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100839 if (ispresent(g_pars.p_tmsi)) {
840 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
841 } else {
842 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
843 }
844}
845
Harald Welte311ec272018-02-17 09:40:03 +0100846private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100847 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100848 /* Expect MSC to perform LU with HLR */
849 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100850 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
851 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
852 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100853 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
854 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
855}
856
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100857friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0,
858 template (omit) RoutingAreaIdentificationV old_ra := omit) runs on BSSGP_ConnHdlr {
859 var RoutingAreaIdentificationV old_ra_val;
860 var template PDU_L3_MS_SGSN attach_req;
Harald Welteca362462019-05-02 20:11:21 +0200861 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100862
Pau Espin Pedrol7c052162021-02-12 17:43:35 +0100863 if (istemplatekind(old_ra, "omit")) {
864 old_ra_val := f_random_RAI();
865 } else {
866 old_ra_val := valueof(old_ra);
867 }
868
869 attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra_val, false, false, omit, omit);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200870 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
871 * 3G auth vectors */
872 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
873 /* The thing is, if the solSACapability is 'omit', then the
874 * revisionLevelIndicatior is at the wrong place! */
875 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
876
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200877 f_send_l3(attach_req, ran_index);
878 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200879 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100880 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100881
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200882 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Pau Espin Pedrold792b9e2021-02-12 19:49:59 +0100883 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept, ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200884
Harald Welte04683d02018-02-16 22:43:45 +0100885 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200886 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200887
888 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200889 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200890 as_iu_release_compl_disc();
891 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200892
893 /* Race condition
894 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
895 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
896 * arrived before it. This results in a test case failure.
897 * Delay execution by 50 ms
898 */
899 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200900}
901
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200902friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
903 timer T := 5.0;
904 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100905 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 +0200906 T.start;
907 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100908 [] 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 +0200909 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
910 }
Harald Welte9b461a92020-12-10 23:41:14 +0100911 [] 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 +0200912 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
913 mtc.stop;
914 }
915 [] T.timeout {
916 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
917 mtc.stop;
918 }
919 }
920 return '00'O;
921}
922
923friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
924 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100925 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 +0200926 T.start;
927 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100928 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
929 [] 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 +0200930?)) {
931 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
932 mtc.stop;
933 }
934 [] T.timeout {
935 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
936 mtc.stop;
937 }
938 }
939}
940
941
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200942private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
943 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100944 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100945}
946
947testcase TC_attach() runs on test_CT {
948 var BSSGP_ConnHdlr vc_conn;
949 f_init();
950 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200951 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100952 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200953 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100954}
955
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100956testcase TC_attach_mnc3() runs on test_CT {
957 var BSSGP_ConnHdlr vc_conn;
958 f_init('023042'H);
959 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200960 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100961 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200962 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100963}
964
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200965private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
966 f_gmm_attach(true, false);
967 setverdict(pass);
968}
969testcase TC_attach_umts_aka_umts_res() runs on test_CT {
970 var BSSGP_ConnHdlr vc_conn;
971 f_init();
972 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200973 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200974 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200975 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200976}
977
978private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
979 f_gmm_attach(true, true);
980 setverdict(pass);
981}
982testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
983 var BSSGP_ConnHdlr vc_conn;
984 f_init();
985 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200986 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200987 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200988 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200989}
990
Harald Welte5b7c8122018-02-16 21:48:17 +0100991/* MS never responds to ID REQ, expect ATTACH REJECT */
992private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100993 var RoutingAreaIdentificationV old_ra := f_random_RAI();
994
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200995 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100996 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200997 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100998 /* don't send ID Response */
999 repeat;
1000 }
Harald Welte955aa942019-05-03 01:29:29 +02001001 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001002 setverdict(pass);
1003 }
Harald Welte955aa942019-05-03 01:29:29 +02001004 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001005 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +02001006 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001007 }
1008 }
1009}
1010testcase TC_attach_auth_id_timeout() runs on test_CT {
1011 var BSSGP_ConnHdlr vc_conn;
1012 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001013 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 +01001014 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001015 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001016}
1017
1018/* HLR never responds to SAI REQ, expect ATTACH REJECT */
1019private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +01001020 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1021
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001022 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001023 alt {
1024 [] as_mm_identity();
1025 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1026 }
1027 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001028 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001029 setverdict(pass);
1030}
1031testcase TC_attach_auth_sai_timeout() runs on test_CT {
1032 var BSSGP_ConnHdlr vc_conn;
1033 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001034 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001035 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001036 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001037}
1038
Harald Weltefe253882018-02-17 09:25:00 +01001039/* HLR rejects SAI, expect ATTACH REJECT */
1040private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001041 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1042
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001043 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001044 alt {
1045 [] as_mm_identity();
1046 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1047 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1048 }
1049 }
Harald Welte955aa942019-05-03 01:29:29 +02001050 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001051 setverdict(pass);
1052}
1053testcase TC_attach_auth_sai_reject() runs on test_CT {
1054 var BSSGP_ConnHdlr vc_conn;
1055 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001056 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001057 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001058 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001059}
1060
Harald Welte5b7c8122018-02-16 21:48:17 +01001061/* HLR never responds to UL REQ, expect ATTACH REJECT */
1062private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001063 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001064 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1065
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001066 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001067 f_gmm_auth();
1068 /* Expect MSC to perform LU with HLR */
1069 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1070 /* Never follow-up with ISD_REQ or UL_RES */
1071 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001072 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001073 setverdict(pass);
1074 }
Harald Welte955aa942019-05-03 01:29:29 +02001075 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1076 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001077 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001078 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001079 }
1080 }
1081}
1082testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1083 var BSSGP_ConnHdlr vc_conn;
1084 f_init();
1085 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001086 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001088 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001089}
1090
Harald Welteb7c14e92018-02-17 09:29:16 +01001091/* HLR rejects UL REQ, expect ATTACH REJECT */
1092private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001093 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001094 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1095
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001096 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001097 f_gmm_auth();
1098 /* Expect MSC to perform LU with HLR */
1099 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1100 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1101 }
1102 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001103 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001104 setverdict(pass);
1105 }
Harald Welte955aa942019-05-03 01:29:29 +02001106 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1107 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001108 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001109 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001110 }
1111 }
1112}
1113testcase TC_attach_gsup_lu_reject() runs on test_CT {
1114 var BSSGP_ConnHdlr vc_conn;
1115 f_init();
1116 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001117 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001118 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001119 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001120}
1121
1122
Harald Welte3823e2e2018-02-16 21:53:48 +01001123/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1124private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001125 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001126 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1127
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001128 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001129 f_gmm_auth();
1130 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001131 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001132
Harald Welte955aa942019-05-03 01:29:29 +02001133 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1134 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001135 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001136 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001137 setverdict(pass);
1138}
Harald Welte3823e2e2018-02-16 21:53:48 +01001139testcase TC_attach_combined() runs on test_CT {
1140 var BSSGP_ConnHdlr vc_conn;
1141 f_init();
1142 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001143 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001144 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001145 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001146}
1147
Harald Welte76dee092018-02-16 22:12:59 +01001148/* Attempt of GPRS ATTACH in 'accept all' mode */
1149private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001150 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001151 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1152
1153 g_pars.net.expect_auth := false;
1154
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001155 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001156 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001157 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1158 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001159 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001160 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001161 setverdict(pass);
1162}
1163testcase TC_attach_accept_all() runs on test_CT {
1164 var BSSGP_ConnHdlr vc_conn;
1165 f_init();
1166 f_sleep(1.0);
1167 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001168 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001169 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001170 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001171}
Harald Welte5b7c8122018-02-16 21:48:17 +01001172
Harald Welteb2124b22018-02-16 22:26:56 +01001173/* Attempt of GPRS ATTACH in 'accept all' mode */
1174private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001175 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1176
1177 /* Simulate a foreign IMSI */
1178 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001179 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001180
1181 g_pars.net.expect_auth := false;
1182
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001183 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001184 alt {
1185 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001186 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001187 setverdict(pass);
1188 }
Harald Welte955aa942019-05-03 01:29:29 +02001189 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001190 setverdict(pass);
1191 }
Harald Welte955aa942019-05-03 01:29:29 +02001192 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001193 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001194 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001195 }
Harald Welteb2124b22018-02-16 22:26:56 +01001196 }
1197}
1198testcase TC_attach_closed() runs on test_CT {
1199 var BSSGP_ConnHdlr vc_conn;
1200 f_init();
1201 f_sleep(1.0);
1202 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1203 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001204 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001205 vc_conn.done;
1206 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001207 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001208 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001209 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001210}
1211
Harald Welte04683d02018-02-16 22:43:45 +01001212/* Routing Area Update from Unknown TLLI -> REJECT */
1213private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001214 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1215
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001216 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 +01001217 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001218 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001219 setverdict(pass);
1220 }
1221 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001222 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001223 }
1224}
1225testcase TC_rau_unknown() runs on test_CT {
1226 var BSSGP_ConnHdlr vc_conn;
1227 f_init();
1228 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001229 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001230 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001231 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001232}
1233
Harald Welte91636de2018-02-17 10:16:14 +01001234private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001235 /* first perform regular attach */
1236 f_TC_attach(id);
1237
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001238 f_routing_area_update(g_pars.ra);
1239
Harald Welte91636de2018-02-17 10:16:14 +01001240}
1241testcase TC_attach_rau() runs on test_CT {
1242 var BSSGP_ConnHdlr vc_conn;
1243 f_init();
1244 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001245 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001246 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001247 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001248}
Harald Welte04683d02018-02-16 22:43:45 +01001249
Harald Welte6abb9fe2018-02-17 15:24:48 +01001250/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001251function 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 +02001252 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001253 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001254 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001255 if (expect_purge) {
1256 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1257 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1258 }
1259 T.start;
1260 alt {
1261 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1262 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001263 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001264 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001265 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001266 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001267 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001268 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001269 /* TODO: check if any PDP contexts are deactivated on network side? */
1270 }
1271 [power_off] T.timeout {
1272 setverdict(pass);
1273 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001274 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001275 g_pars.ra := omit;
1276 setverdict(pass);
1277 /* TODO: check if any PDP contexts are deactivated on network side? */
1278 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001279 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001280 if (power_off) {
1281 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1282 } else {
1283 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1284 }
1285 mtc.stop;
1286 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001287 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001288 }
1289}
1290
1291/* IMSI DETACH (non-power-off) for unknown TLLI */
1292private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1293 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1294}
1295testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1296 var BSSGP_ConnHdlr vc_conn;
1297 f_init();
1298 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001299 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001300 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001301 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001302}
1303
1304/* IMSI DETACH (power-off) for unknown TLLI */
1305private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1306 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1307}
1308testcase TC_detach_unknown_poweroff() runs on test_CT {
1309 var BSSGP_ConnHdlr vc_conn;
1310 f_init();
1311 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001312 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001313 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001314 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001315}
1316
1317/* IMSI DETACH (non-power-off) for known TLLI */
1318private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1319 /* first perform regular attach */
1320 f_TC_attach(id);
1321
1322 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1323}
1324testcase TC_detach_nopoweroff() runs on test_CT {
1325 var BSSGP_ConnHdlr vc_conn;
1326 f_init();
1327 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001328 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001329 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001330 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001331}
1332
1333/* IMSI DETACH (power-off) for known TLLI */
1334private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1335 /* first perform regular attach */
1336 f_TC_attach(id);
1337
1338 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1339}
1340testcase TC_detach_poweroff() runs on test_CT {
1341 var BSSGP_ConnHdlr vc_conn;
1342 f_init();
1343 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001344 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001345 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001346 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001347}
1348
Harald Welteeded9ad2018-02-17 20:57:34 +01001349type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001350 BIT3 tid, /* L3 Transaction ID */
1351 BIT4 nsapi, /* SNDCP NSAPI */
1352 BIT4 sapi, /* LLC SAPI */
1353 QoSV qos, /* QoS parameters */
1354 PDPAddressV addr, /* IP address */
1355 octetstring apn optional, /* APN name */
1356 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1357 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001358 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001359 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001360
Harald Welte822f9102018-02-18 20:39:06 +01001361 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1362 OCT4 ggsn_tei_u, /* GGSN TEI User */
1363 octetstring ggsn_ip_c, /* GGSN IP Control */
1364 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001365 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001366
Harald Welte822f9102018-02-18 20:39:06 +01001367 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1368 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1369 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1370 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001371};
1372
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001373
1374private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1375 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1376 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1377 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1378 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1379 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1380 f_gtp_register_teid(apars.ggsn_tei_c);
1381 f_gtp_register_teid(apars.ggsn_tei_u);
1382}
1383
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001384function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001385runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001386 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1387 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001388 var template Recovery_gtpc recovery := omit;
1389
1390 if (send_recovery) {
1391 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1392 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001393
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001394 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 +02001395 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001396 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1397 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1398 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1399 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1400 apars.sgsn_tei_c, apars.gtp_resp_cause,
1401 apars.ggsn_tei_c, apars.ggsn_tei_u,
1402 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001403 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1404 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001405 }
1406 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001407 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001408 setverdict(pass);
1409 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001410 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001411 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001412 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001413 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001414 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001415 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001416 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001417 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001418 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001419 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1420 mtc.stop;
1421 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001422 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001423 setverdict(pass);
1424 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001425 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001426 }
1427}
1428
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001429function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001430runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001431 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1432 var Gtp1cUnitdata g_ud;
1433
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001434 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001435 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1436 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001437 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001438 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1439 }
1440 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001441 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001442 setverdict(pass);
1443 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001444 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001445 }
1446}
1447
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001448function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001449runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001450 var Gtp1cUnitdata g_ud;
1451 var integer seq_nr := 23;
1452 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1453
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001454 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001455 if (error_ind) {
1456 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1457 } else {
1458 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1459 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001460
1461 timer T := 5.0;
1462 T.start;
1463
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001464 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001465 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1466 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001467 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001468 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1469 repeat;
1470 }
1471 [] T.timeout {
1472 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1473 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001474 }
1475}
1476
Harald Welte6f203162018-02-18 22:04:55 +01001477
Harald Welteeded9ad2018-02-17 20:57:34 +01001478/* Table 10.5.156/3GPP TS 24.008 */
1479template (value) QoSV t_QosDefault := {
1480 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1481 delayClass := '100'B, /* best effort */
1482 spare1 := '00'B,
1483 precedenceClass := '010'B, /* normal */
1484 spare2 := '0'B,
1485 peakThroughput := '0000'B, /* subscribed */
1486 meanThroughput := '00000'B, /* subscribed */
1487 spare3 := '000'B,
1488 deliverErroneusSDU := omit,
1489 deliveryOrder := omit,
1490 trafficClass := omit,
1491 maxSDUSize := omit,
1492 maxBitrateUplink := omit,
1493 maxBitrateDownlink := omit,
1494 sduErrorRatio := omit,
1495 residualBER := omit,
1496 trafficHandlingPriority := omit,
1497 transferDelay := omit,
1498 guaranteedBitRateUplink := omit,
1499 guaranteedBitRateDownlink := omit,
1500 sourceStatisticsDescriptor := omit,
1501 signallingIndication := omit,
1502 spare4 := omit,
1503 maxBitrateDownlinkExt := omit,
1504 guaranteedBitRateDownlinkExt := omit,
1505 maxBitrateUplinkExt := omit,
1506 guaranteedBitRateUplinkExt := omit,
1507 maxBitrateDownlinkExt2 := omit,
1508 guaranteedBitRateDownlinkExt2 := omit,
1509 maxBitrateUplinkExt2 := omit,
1510 guaranteedBitRateUplinkExt2 := omit
1511}
1512
1513/* 10.5.6.4 / 3GPP TS 24.008 */
1514template (value) PDPAddressV t_AddrIPv4dyn := {
1515 pdpTypeOrg := '0001'B, /* IETF */
1516 spare := '0000'B,
1517 pdpTypeNum := '21'O, /* IPv4 */
1518 addressInfo := omit
1519}
1520template (value) PDPAddressV t_AddrIPv6dyn := {
1521 pdpTypeOrg := '0001'B, /* IETF */
1522 spare := '0000'B,
1523 pdpTypeNum := '53'O, /* IPv6 */
1524 addressInfo := omit
1525}
1526
Harald Welte37692d82018-02-18 15:21:34 +01001527template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001528 tid := '000'B,
1529 nsapi := '0101'B, /* < 5 are reserved */
1530 sapi := '0011'B, /* 3/5/9/11 */
1531 qos := t_QosDefault,
1532 addr := t_AddrIPv4dyn,
1533 apn := omit,
1534 pco := omit,
1535 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001536 gtp_resp_cause := int2oct(128, 1),
1537 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001538
1539 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001540 ggsn_tei_c := f_rnd_octstring(4),
1541 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001542 ggsn_ip_c := f_inet_addr(ggsn_ip),
1543 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001544 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001545
Harald Welteeded9ad2018-02-17 20:57:34 +01001546 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001547 sgsn_tei_u := omit,
1548 sgsn_ip_c := omit,
1549 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001550}
1551
Harald Welte37692d82018-02-18 15:21:34 +01001552template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1553 connId := 1,
1554 remName := f_inet_ntoa(ip),
1555 remPort := GTP1U_PORT
1556}
1557
1558template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1559 connId := 1,
1560 remName := f_inet_ntoa(ip),
1561 remPort := GTP1C_PORT
1562}
1563
1564private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1565 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1566 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1567}
1568
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001569private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1570 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001571 repeat;
1572 }
1573}
1574
1575template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1576 pDU_SN_UNITDATA := {
1577 nsapi := nsapi,
1578 moreBit := ?,
1579 snPduType := '1'B,
1580 firstSegmentIndicator := ?,
1581 spareBit := ?,
1582 pcomp := ?,
1583 dcomp := ?,
1584 npduNumber := ?,
1585 segmentNumber := ?,
1586 npduNumberContinued := ?,
1587 dataSegmentSnUnitdataPdu := payload
1588 }
1589}
1590
1591/* simple case: single segment, no compression */
1592template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1593 pDU_SN_UNITDATA := {
1594 nsapi := nsapi,
1595 moreBit := '0'B,
1596 snPduType := '1'B,
1597 firstSegmentIndicator := '1'B,
1598 spareBit := '0'B,
1599 pcomp := '0000'B,
1600 dcomp := '0000'B,
1601 npduNumber := '0000'B,
1602 segmentNumber := '0000'B,
1603 npduNumberContinued := '00'O,
1604 dataSegmentSnUnitdataPdu := payload
1605 }
1606}
1607
1608/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001609private 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 +02001610runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001611 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001612 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1613 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001614 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001615 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1616 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001617 [] as_xid(apars, ran_index);
1618 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001619 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1620 [expect_fwd] T.timeout {
1621 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1622 mtc.stop;
1623 }
1624 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1625 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1626 mtc.stop;
1627 }
1628 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001629 }
1630}
1631
Harald Welte64d6b512020-06-17 16:42:00 +02001632/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001633private 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 +02001634runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001635 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1636 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1637 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01001638 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, n_u));
Harald Welte37692d82018-02-18 15:21:34 +01001639 /* Expect PDU via GTP from SGSN on simulated GGSN */
1640 alt {
1641 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1642 }
1643}
1644
Harald Welteeded9ad2018-02-17 20:57:34 +01001645private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001646 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001647
1648 /* first perform regular attach */
1649 f_TC_attach(id);
1650
1651 f_pdp_ctx_act(apars);
1652}
1653testcase TC_attach_pdp_act() runs on test_CT {
1654 var BSSGP_ConnHdlr vc_conn;
1655 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001656 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001657 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001658 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001659}
Harald Welteb2124b22018-02-16 22:26:56 +01001660
Harald Welte835b15f2018-02-18 14:39:11 +01001661/* PDP Context activation for not-attached subscriber; expect fail */
1662private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001663 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001664 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 +01001665 apars.apn, apars.pco));
1666 alt {
1667 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001668 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001669 setverdict(pass);
1670 }
1671 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1672 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001673 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001674 }
Harald Welte955aa942019-05-03 01:29:29 +02001675 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001676 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001677 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001678 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001679 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001680 }
1681}
1682testcase TC_pdp_act_unattached() runs on test_CT {
1683 var BSSGP_ConnHdlr vc_conn;
1684 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001685 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001686 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001687 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001688}
1689
Harald Welte37692d82018-02-18 15:21:34 +01001690/* ATTACH + PDP CTX ACT + user plane traffic */
1691private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1692 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1693
1694 /* first perform regular attach */
1695 f_TC_attach(id);
1696 /* then activate PDP context */
1697 f_pdp_ctx_act(apars);
1698 /* then transceive a downlink PDU */
1699 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1700 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1701}
1702testcase TC_attach_pdp_act_user() runs on test_CT {
1703 var BSSGP_ConnHdlr vc_conn;
1704 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001705 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001706 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001707 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001708}
1709
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001710/* ATTACH + PDP CTX ACT; reject from GGSN */
1711private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1712 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1713
1714 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1715 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1716
1717 /* first perform regular attach */
1718 f_TC_attach(id);
1719 /* then activate PDP context */
1720 f_pdp_ctx_act(apars);
1721}
1722testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1723 var BSSGP_ConnHdlr vc_conn;
1724 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001725 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001726 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001727 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001728}
Harald Welte835b15f2018-02-18 14:39:11 +01001729
Harald Welte6f203162018-02-18 22:04:55 +01001730/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1731private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1732 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1733
1734 /* first perform regular attach */
1735 f_TC_attach(id);
1736 /* then activate PDP context */
1737 f_pdp_ctx_act(apars);
1738 /* then transceive a downlink PDU */
1739 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1740 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1741
1742 f_pdp_ctx_deact_mo(apars, '00'O);
1743}
1744testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1745 var BSSGP_ConnHdlr vc_conn;
1746 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001747 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 +01001748 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001749 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001750}
1751
Harald Welte57b9b7f2018-02-18 22:28:13 +01001752/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1753private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1754 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1755
1756 /* first perform regular attach */
1757 f_TC_attach(id);
1758 /* then activate PDP context */
1759 f_pdp_ctx_act(apars);
1760 /* then transceive a downlink PDU */
1761 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1762 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1763
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001764 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001765}
1766testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1767 var BSSGP_ConnHdlr vc_conn;
1768 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001769 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 +01001770 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001771 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001772}
1773
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001774/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1775private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1776 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1777 var Gtp1cUnitdata g_ud;
1778 var integer i;
1779 var OCT1 cause_regular_deact := '24'O;
1780
1781 /* first perform regular attach + PDP context act */
1782 f_TC_attach(id);
1783 f_pdp_ctx_act(apars);
1784
1785 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1786 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1787
1788 for (i := 0; i < 2; i := i+1) {
1789 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1790 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1791 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1792 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1793 }
1794 }
1795
1796 alt {
1797 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1798 setverdict(pass);
1799 }
1800 [] as_xid(apars, 0);
1801 }
1802
1803 /* Make sure second DeactPdpAccept is sent: */
1804 timer T := 2.0;
1805 T.start;
1806 alt {
1807 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1808 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1809 }
1810 [] T.timeout {
1811 setverdict(pass);
1812 }
1813 }
1814
1815 setverdict(pass);
1816}
1817testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1818 var BSSGP_ConnHdlr vc_conn;
1819 f_init();
1820 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1821 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001822 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001823}
1824
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001825/* ATTACH + ATTACH (2nd) */
1826private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1827 g_pars.t_guard := 5.0;
1828
1829 /* first perform regular attach */
1830 f_TC_attach(id);
1831
1832 /* second to perform regular attach */
1833 f_TC_attach(id);
1834}
1835
1836
1837testcase TC_attach_second_attempt() runs on test_CT {
1838 var BSSGP_ConnHdlr vc_conn;
1839 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001840 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001841 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001842 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001843}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001844
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001845private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1846 var Gtp1cUnitdata g_ud;
1847 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1848 var integer seq_nr;
1849
1850 /* first perform regular attach */
1851 f_TC_attach(id);
1852 /* then activate PDP context */
1853 f_pdp_ctx_act(apars);
1854
1855 /* Wait to receive first echo request and send initial Restart counter */
1856 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1857 BSSGP[0].clear;
1858 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1859 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1860 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1861 }
1862
1863 /* At some point next echo request not answered will timeout and SGSN
1864 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1865 timer T := 3.0 * 6.0 + 16.0;
1866 T.start;
1867 alt {
1868 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1869 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1870 setverdict(pass);
1871 }
1872 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1873 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1874 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1875 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1876 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1877 repeat;
1878 }
1879 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1880 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1881 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1882 repeat;
1883 }
1884 [] T.timeout {
1885 setverdict(fail, "BSSGP DeactPdpReq not received");
1886 mtc.stop;
1887 }
1888 [] as_xid(apars);
1889 }
1890 T.stop
1891
1892 setverdict(pass);
1893}
1894/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1895testcase TC_attach_echo_timeout() runs on test_CT {
1896 var BSSGP_ConnHdlr vc_conn;
1897 g_use_echo := true;
1898 f_init();
1899 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1900 vc_conn.done;
1901 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001902 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001903}
1904
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001905private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001906 var Gtp1cUnitdata g_ud;
1907 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1908
1909 /* first perform regular attach */
1910 f_TC_attach(id);
1911 /* Activate a pdp context against the GGSN */
1912 f_pdp_ctx_act(apars);
1913 /* Wait to receive first echo request and send initial Restart counter */
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 /* Wait to receive second echo request and send incremented Restart
1919 counter. This will fake a restarted GGSN, and pdp ctx allocated
1920 should be released by SGSN */
1921 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1922 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1923 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1924 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1925 }
1926 var OCT1 cause_network_failure := int2oct(38, 1)
1927 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001928 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001929 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001930 setverdict(pass);
1931 }
1932 [] as_xid(apars);
1933 }
1934 setverdict(pass);
1935}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001936/* ATTACH + trigger Recovery procedure through EchoResp */
1937testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001938 var BSSGP_ConnHdlr vc_conn;
1939 g_use_echo := true
1940 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001941 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 +02001942 vc_conn.done;
1943 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001944 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001945}
1946
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001947private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1948 var Gtp1cUnitdata g_ud;
1949 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1950 var integer seq_nr := 23;
1951 var GtpPeer peer;
1952 /* first perform regular attach */
1953 f_TC_attach(id);
1954
1955 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1956 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1957 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1958 f_pdp_ctx_act(apars, true);
1959
1960 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1961/* received. */
1962 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1963
1964 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1965 would be great to have an active pdp context here before triggering
1966 Recovery, and making sure the the DEACT request is sent by the SGSN.
1967 */
1968
1969 /* Activate a pdp context against the GGSN, send incremented Recovery
1970 IE. This should trigger the recovery path, but still this specific
1971 CTX activation should work. */
1972 apars.exp_rej_cause := omit; /* default value for tests */
1973 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1974 f_pdp_ctx_act(apars, true);
1975
1976 setverdict(pass);
1977}
1978/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1979testcase TC_attach_restart_ctr_create() runs on test_CT {
1980 var BSSGP_ConnHdlr vc_conn;
1981 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001982 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 +02001983 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001984 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001985}
1986
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001987/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1988private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1989 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1990 var integer seq_nr := 23;
1991 var GtpPeer peer;
1992 var integer i;
1993
1994 /* first perform regular attach */
1995 f_TC_attach(id);
1996 /* then activate PDP context */
1997 f_pdp_ctx_act(apars);
1998
Alexander Couzens0e510e62018-07-28 23:06:00 +02001999 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002000 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2001 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
2002
2003 for (i := 0; i < 5; i := i+1) {
2004 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002005 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002006 [] as_xid(apars);
2007 }
2008 }
2009
2010 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
2011
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002012 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002013 setverdict(pass);
2014}
2015testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
2016 var BSSGP_ConnHdlr vc_conn;
2017 f_init();
2018 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002019 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 +02002020 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002021 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002022}
2023
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002024/* ATTACH + PDP CTX ACT dropped + retrans */
2025private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2026 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2027 var Gtp1cUnitdata g_ud_first, g_ud_second;
2028 /* first perform regular attach */
2029 f_TC_attach(id);
2030
2031 /* then activate PDP context on the Gb side */
2032 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2033 apars.apn, apars.pco), 0);
2034
2035 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2036 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2037 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2038 if (g_ud_first != g_ud_second) {
2039 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2040 mtc.stop;
2041 }
2042 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2043 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2044 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2045 apars.sgsn_tei_c, apars.gtp_resp_cause,
2046 apars.ggsn_tei_c, apars.ggsn_tei_u,
2047 apars.nsapi,
2048 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2049 omit, omit));
2050 }
Harald Welte955aa942019-05-03 01:29:29 +02002051 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002052
2053 /* Now the same with Deact */
2054 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2055 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2056 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2057 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2058 if (g_ud_first != g_ud_second) {
2059 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2060 mtc.stop;
2061 }
2062 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2063 BSSGP[0].clear;
2064 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2065 }
2066 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002067 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002068 setverdict(pass);
2069 }
2070 [] as_xid(apars, 0);
2071 }
2072
2073 setverdict(pass);
2074}
2075testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2076 var BSSGP_ConnHdlr vc_conn;
2077 f_init();
2078 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2079 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002080 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002081}
2082
2083/* Test that SGSN GTP response retransmit queue works fine */
2084private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2085 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2086 var integer seq_nr := 23;
2087 var Gtp1cUnitdata g_ud_first, g_ud_second;
2088 var template Gtp1cUnitdata g_delete_req;
2089 /* first perform regular attach + PDP context act */
2090 f_TC_attach(id);
2091 f_pdp_ctx_act(apars);
2092
2093 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2094 BSSGP[0].clear;
2095 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2096 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2097 GTP.send(g_delete_req);
2098 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002099 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002100 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2101 }
2102 [] as_xid(apars, 0);
2103 }
2104 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2105 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2106 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2107 mtc.stop;
2108 }
2109 };
2110
2111 /* Send duplicate DeleteCtxReq */
2112 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2113 GTP.send(g_delete_req);
2114 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2115 if (g_ud_first != g_ud_second) {
2116 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2117 mtc.stop;
2118 }
2119 }
2120
2121 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2122 * is handled differently by SGSN (expect "non-existent" cause) */
2123 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2124 GTP.send(g_delete_req);
2125 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2126 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2127 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2128 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2129 mtc.stop;
2130 }
2131 }
2132
2133 setverdict(pass);
2134}
2135testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2136 var BSSGP_ConnHdlr vc_conn;
2137 f_init();
2138 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2139 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002140 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002141}
2142
Alexander Couzens5e307b42018-05-22 18:12:20 +02002143private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2144 /* MS: perform regular attach */
2145 f_TC_attach(id);
2146
2147 /* HLR: cancel the location request */
2148 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2149 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002150
2151 /* ensure no Detach Request got received */
2152 timer T := 5.0;
2153 T.start;
2154 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002155 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002156 T.stop;
2157 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002158 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002159 }
2160 [] T.timeout {
2161 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002162 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002163 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002164 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002165 repeat;
2166 }
2167 }
2168}
2169
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002170/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2171private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2172 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2173
2174 /* first perform regular attach */
2175 f_TC_attach(id);
2176 /* then activate PDP context */
2177 f_pdp_ctx_act(apars);
2178 /* then transceive a downlink PDU */
2179 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2180
2181 /* Send Error indication as response from upload PDU and expect deact towards MS */
2182 f_pdp_ctx_deact_mt(apars, true);
2183}
2184testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2185 var BSSGP_ConnHdlr vc_conn;
2186 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002187 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 +02002188 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002189 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002190}
2191
Alexander Couzens5e307b42018-05-22 18:12:20 +02002192testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2193 /* MS <-> SGSN: GMM Attach
2194 * HLR -> SGSN: Cancel Location Request
2195 * HLR <- SGSN: Cancel Location Ack
2196 */
2197 var BSSGP_ConnHdlr vc_conn;
2198 f_init();
2199 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002200 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002201 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002202 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002203}
2204
2205
Alexander Couzensc87967a2018-05-22 16:09:54 +02002206private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2207 /* MS: perform regular attach */
2208 f_TC_attach(id);
2209
2210 /* HLR: cancel the location request */
2211 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2212 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2213 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2214
2215 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002216 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002217 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002218
2219 setverdict(pass);
2220}
2221
2222testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2223 /* MS <-> SGSN: GMM Attach
2224 * HLR -> SGSN: Cancel Location Request
2225 * HLR <- SGSN: Cancel Location Ack
2226 * MS <- SGSN: Detach Request
2227 * SGSN-> MS: Detach Complete
2228 */
2229 var BSSGP_ConnHdlr vc_conn;
2230 f_init();
2231 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002232 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002233 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002234 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002235}
2236
2237
Alexander Couzens6c47f292018-05-22 17:09:49 +02002238private function f_hlr_location_cancel_request_unknown_subscriber(
2239 charstring id,
2240 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2241
2242 /* HLR: cancel the location request */
2243 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2244
2245 /* cause 2 = IMSI_UNKNOWN */
2246 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2247
2248 setverdict(pass);
2249}
2250
2251private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002252 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002253}
2254
2255testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2256 /* HLR -> SGSN: Cancel Location Request
2257 * HLR <- SGSN: Cancel Location Error
2258 */
2259
2260 var BSSGP_ConnHdlr vc_conn;
2261 f_init();
2262 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002263 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 +02002264 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002265 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002266}
2267
2268private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002269 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002270}
2271
2272testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2273 /* HLR -> SGSN: Cancel Location Request
2274 * HLR <- SGSN: Cancel Location Error
2275 */
2276
2277 var BSSGP_ConnHdlr vc_conn;
2278 f_init();
2279 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002280 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 +02002281 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002282 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002283}
2284
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002285private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2286 f_TC_attach(id);
2287 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2288}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002289
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002290testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2291 /* MS <-> SGSN: Attach
2292 * MS -> SGSN: Detach Req (Power off)
2293 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2294 */
2295 var BSSGP_ConnHdlr vc_conn;
2296 var integer id := 33;
2297 var charstring imsi := hex2str(f_gen_imsi(id));
2298
2299 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002300 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002301 vc_conn.done;
2302
2303 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002304 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002305}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002306
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002307/* Attempt an attach, but loose the Identification Request (IMEI) */
2308private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2309 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002310 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002311
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002312 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 +02002313
2314 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002315 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002316 /* break */
2317 }
Harald Welte955aa942019-05-03 01:29:29 +02002318 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002319 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002320 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002321 repeat;
2322 }
Harald Welte955aa942019-05-03 01:29:29 +02002323 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002324 /* ignore ID REQ IMEI */
2325 count_req := count_req + 1;
2326 repeat;
2327 }
2328 }
2329 if (count_req != 5) {
2330 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002331 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002332 }
2333 setverdict(pass);
2334}
2335
2336testcase TC_attach_no_imei_response() runs on test_CT {
2337 /* MS -> SGSN: Attach Request IMSI
2338 * MS <- SGSN: Identity Request IMSI (optional)
2339 * MS -> SGSN: Identity Response IMSI (optional)
2340 * MS <- SGSN: Identity Request IMEI
2341 * MS -x SGSN: no response
2342 * MS <- SGSN: re-send: Identity Request IMEI 4x
2343 * MS <- SGSN: Attach Reject
2344 */
2345 var BSSGP_ConnHdlr vc_conn;
2346 f_init();
2347 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002348 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 +02002349 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002350 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002351}
2352
Alexander Couzens53f20562018-06-12 16:24:12 +02002353/* Attempt an attach, but loose the Identification Request (IMSI) */
2354private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2355 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002356 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002357
2358 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2359 g_pars.p_tmsi := 'c0000035'O;
2360
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002361 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 +02002362
2363 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002364 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002365 /* break */
2366 }
Harald Welte955aa942019-05-03 01:29:29 +02002367 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002368 /* ignore ID REQ IMSI */
2369 count_req := count_req + 1;
2370 repeat;
2371 }
Harald Welte955aa942019-05-03 01:29:29 +02002372 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002373 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002374 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002375 repeat;
2376 }
2377 }
2378 if (count_req != 5) {
2379 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002380 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002381 }
2382 setverdict(pass);
2383}
2384
2385testcase TC_attach_no_imsi_response() runs on test_CT {
2386 /* MS -> SGSN: Attach Request TMSI (unknown)
2387 * MS <- SGSN: Identity Request IMEI (optional)
2388 * MS -> SGSN: Identity Response IMEI (optional)
2389 * MS <- SGSN: Identity Request IMSI
2390 * MS -x SGSN: no response
2391 * MS <- SGSN: re-send: Identity Request IMSI 4x
2392 * MS <- SGSN: Attach Reject
2393 */
2394 var BSSGP_ConnHdlr vc_conn;
2395 f_init();
2396 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002397 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 +02002398 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002399 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002400}
2401
Alexander Couzenscf818962018-06-05 18:00:00 +02002402private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2403 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2404}
2405
2406testcase TC_attach_check_subscriber_list() runs on test_CT {
2407 /* MS <-> SGSN: Attach
2408 * VTY -> SGSN: Check if MS is in subscriber cache
2409 */
2410 var BSSGP_ConnHdlr vc_conn;
2411 var integer id := 34;
2412 var charstring imsi := hex2str(f_gen_imsi(id));
2413
2414 f_init();
2415 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002416 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002417 vc_conn.done;
2418
2419 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2420 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002421 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002422}
2423
Alexander Couzensf9858652018-06-07 16:14:53 +02002424private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2425 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002426 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002427
2428 /* unregister the old IMSI */
2429 f_bssgp_client_unregister(g_pars.imsi);
2430 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002431 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002432 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002433
2434 /* there is no auth */
2435 g_pars.net.expect_auth := false;
2436
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002437 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002438 f_gmm_auth();
2439 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002440 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002441 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002442 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002443 }
Harald Welte955aa942019-05-03 01:29:29 +02002444 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2445 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002446 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002447 setverdict(pass);
2448 }
2449 }
2450}
Alexander Couzens03d12242018-08-07 16:13:52 +02002451
2452private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2453
2454 f_TC_attach_closed_foreign(id);
2455 f_TC_attach_closed_imsi_added(id);
2456
2457}
2458
2459
Alexander Couzensf9858652018-06-07 16:14:53 +02002460testcase TC_attach_closed_add_vty() runs on test_CT {
2461 /* VTY-> SGSN: policy close
2462 * MS -> SGSN: Attach Request
2463 * MS <- SGSN: Identity Request IMSI
2464 * MS -> SGSN: Identity Response IMSI
2465 * MS <- SGSN: Attach Reject
2466 * VTY-> SGSN: policy imsi-acl add IMSI
2467 * MS -> SGSN: Attach Request
2468 * MS <- SGSN: Identity Request IMSI
2469 * MS -> SGSN: Identity Response IMSI
2470 * MS <- SGSN: Identity Request IMEI
2471 * MS -> SGSN: Identity Response IMEI
2472 * MS <- SGSN: Attach Accept
2473 */
2474 var BSSGP_ConnHdlr vc_conn;
2475 f_init();
2476 f_sleep(1.0);
2477 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2478 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002479 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2480 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002481 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002482 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002483 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002484 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002485}
2486
Alexander Couzens0085bd72018-06-12 19:08:44 +02002487/* Attempt an attach, but never answer a Attach Complete */
2488private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2489 var integer count_req := 0;
2490
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002491 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 +02002492 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002493 /* Expect SGSN to perform LU with HLR */
2494 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002495
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002496 timer T := 10.0;
2497 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002498 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002499 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002500 /* break */
2501 }
Harald Welte955aa942019-05-03 01:29:29 +02002502 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002503 /* ignore */
2504 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002505 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002506 repeat;
2507 }
2508 }
2509 if (count_req != 5) {
2510 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002511 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002512 }
2513 setverdict(pass);
2514}
2515
2516testcase TC_attach_check_complete_resend() runs on test_CT {
2517 /* MS -> SGSN: Attach Request IMSI
2518 * MS <- SGSN: Identity Request *
2519 * MS -> SGSN: Identity Response *
2520 * MS <- SGSN: Attach Complete 5x
2521 */
2522 var BSSGP_ConnHdlr vc_conn;
2523 f_init();
2524 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002525 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 +02002526 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002527 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002528}
2529
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002530friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002531 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002532 var PDU_DTAP_PS_MT mt;
2533 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002534
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002535 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002536 p_tmsi := g_pars.p_tmsi;
2537 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002538 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002539 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 +02002540 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002541 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2542 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2543 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002544 setverdict(pass);
2545 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002546 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2547 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2548 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002549 setverdict(pass);
2550 }
2551
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002552 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002553 setverdict(fail, "Unexpected RAU Reject");
2554 mtc.stop;
2555 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002556 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002557 setverdict(fail, "Unexpected RAU Reject");
2558 mtc.stop;
2559 }
2560
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002561 [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 +02002562 key_sts := ?)) {
2563 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2564 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002565 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002566 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002567 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002568 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2569 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002570 }
2571}
2572
Alexander Couzensbfda9212018-07-31 03:17:33 +02002573private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002574 /* first perform regular attach */
2575 f_TC_attach(id);
2576
2577 /* then send RAU */
2578 f_routing_area_update(g_pars.ra);
2579
2580 /* do another RAU */
2581 f_routing_area_update(g_pars.ra);
2582
2583 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2584}
2585
2586testcase TC_attach_rau_a_a() runs on test_CT {
2587 /* MS <-> SGSN: Successful Attach
2588 * MS -> SGSN: Routing Area Update Request
2589 * MS <- SGSN: Routing Area Update Accept
2590 * MS -> SGSN: Routing Area Update Request
2591 * MS <- SGSN: Routing Area Update Accept
2592 * MS -> SGSN: Detach (PowerOff)
2593 */
2594 var BSSGP_ConnHdlr vc_conn;
2595 f_init();
2596 f_sleep(1.0);
2597 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2598 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002599 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002600}
2601
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002602private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002603 f_TC_attach(id);
2604
2605 log("attach complete sending rau");
2606 f_routing_area_update(g_pars.ra, 0);
2607
2608 log("rau complete unregistering");
2609 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002610 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002611
2612 log("sending second RAU via different RA");
2613 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2614
2615 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2616}
2617
2618testcase TC_attach_rau_a_b() runs on test_CT {
2619 /* MS <-> SGSN: Successful Attach
2620 * MS -> SGSN: Routing Area _a_ Update Request
2621 * MS <- SGSN: Routing Area _a_ Update Accept
2622 * MS -> SGSN: Routing Area _b_ Update Request
2623 * MS <- SGSN: Routing Area _b_ Update Accept
2624 * MS -> SGSN: Detach (PowerOff)
2625 */
2626 var BSSGP_ConnHdlr vc_conn;
2627 f_init();
2628 f_sleep(1.0);
2629 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2630 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002631 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002632}
2633
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002634private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2635 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002636 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002637 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002638 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002639
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002640 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002641
2642 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002643 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002644 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2645 mtc.stop;
2646 }
Harald Welte955aa942019-05-03 01:29:29 +02002647 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002648 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002649 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002650 repeat;
2651 }
Harald Welte955aa942019-05-03 01:29:29 +02002652 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002653 /* send out a second GMM_Attach Request.
2654 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2655 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002656 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002657 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002658 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002659 }
2660 }
2661 f_sleep(1.0);
2662
2663 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2664 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002665 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002666 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002667 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002668 repeat;
2669 }
Harald Welte955aa942019-05-03 01:29:29 +02002670 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002671 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2672 mtc.stop;
2673 }
Harald Welte955aa942019-05-03 01:29:29 +02002674 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002675 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2676 mtc.stop;
2677 }
Harald Welte955aa942019-05-03 01:29:29 +02002678 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2679 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002680 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002681 setverdict(pass);
2682 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2683 }
2684 }
2685}
2686
2687testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2688 /* Testing if the SGSN ignore Attach Request with the exact same content */
2689 /* MS -> SGSN: Attach Request IMSI
2690 * MS <- SGSN: Identity Request IMSI (optional)
2691 * MS -> SGSN: Identity Response IMSI (optional)
2692 * MS <- SGSN: Identity Request IMEI
2693 * MS -> SGSN: Attach Request (2nd)
2694 * MS <- SGSN: Identity Response IMEI
2695 * MS <- SGSN: Attach Accept
2696 * MS -> SGSN: Attach Complete
2697 */
2698 var BSSGP_ConnHdlr vc_conn;
2699 f_init();
2700 f_sleep(1.0);
2701 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2702 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2703 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002704 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002705}
2706
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002707private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002708 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2709
2710 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2711
2712 /* send Attach Request */
2713 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2714 * 3G auth vectors */
2715 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2716 /* The thing is, if the solSACapability is 'omit', then the
2717 * revisionLevelIndicatior is at the wrong place! */
2718 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002719 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002720
2721 /* do the auth */
2722 var PDU_L3_MS_SGSN l3_mo;
2723 var PDU_L3_SGSN_MS l3_mt;
2724 var default di := activate(as_mm_identity());
2725
2726 var GSUP_IE auth_tuple;
2727 var template AuthenticationParameterAUTNTLV autn;
2728
2729 g_pars.vec := f_gen_auth_vec_3g();
2730 autn := {
2731 elementIdentifier := '28'O,
2732 lengthIndicator := lengthof(g_pars.vec.autn),
2733 autnValue := g_pars.vec.autn
2734 };
2735 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2736 g_pars.vec.sres,
2737 g_pars.vec.kc,
2738 g_pars.vec.ik,
2739 g_pars.vec.ck,
2740 g_pars.vec.autn,
2741 g_pars.vec.res));
2742 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2743 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2744 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2745
2746 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2747 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002748 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002749
2750 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002751 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002752
2753 /* wait for the GSUP resync request */
2754 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2755 g_pars.imsi,
2756 g_pars.vec.auts,
2757 g_pars.vec.rand));
2758
2759 /* generate new key material */
2760 g_pars.vec := f_gen_auth_vec_3g();
2761 autn := {
2762 elementIdentifier := '28'O,
2763 lengthIndicator := lengthof(g_pars.vec.autn),
2764 autnValue := g_pars.vec.autn
2765 };
2766
2767 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2768 g_pars.vec.sres,
2769 g_pars.vec.kc,
2770 g_pars.vec.ik,
2771 g_pars.vec.ck,
2772 g_pars.vec.autn,
2773 g_pars.vec.res));
2774 /* send new key material */
2775 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2776
2777 /* wait for the new Auth Request */
2778 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2779 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002780 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002781 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2782 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2783 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2784 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2785 valueField := substr(g_pars.vec.res, 0, 4)
2786 };
2787 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2788 elementIdentifier := '21'O,
2789 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2790 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2791 };
2792 l3_mo := valueof(auth_ciph_resp);
2793 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2794 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2795 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2796 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2797 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002798 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002799 deactivate(di);
2800
2801 /* Expect SGSN to perform LU with HLR */
2802 f_gmm_gsup_lu_isd();
2803
Harald Welte955aa942019-05-03 01:29:29 +02002804 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2805 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002806 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002807 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002808 setverdict(pass);
2809}
2810
2811testcase TC_attach_usim_resync() runs on test_CT {
2812 /* MS -> SGSN: Attach Request
2813 * MS <- SGSN: Identity Request IMSI
2814 * MS -> SGSN: Identity Response IMSI
2815 * MS <- SGSN: Identity Request IMEI
2816 * MS -> SGSN: Identity Response IMEI
2817 * HLR<- SGSN: SAI Request
2818 * HLR-> SGSN: SAI Response
2819 * MS <- SGSN: Auth Request
2820 * MS -> SGSN: Auth Failure (with AUTS)
2821 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2822 * HLR-> SGSN: SAI Response (new key material)
2823 * MS <- SGSN: Auth Request (new key material)
2824 * MS -> SGSN: Auth Response
2825 * MS <- SGSN: Attach Accept
2826 * MS -> SGSN: Attach Complete
2827 */
2828 var BSSGP_ConnHdlr vc_conn;
2829 f_init();
2830 f_sleep(1.0);
2831 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2832 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002833 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002834}
2835
Harald Weltea05b8072019-04-23 22:35:05 +02002836
2837/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2838private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2839 f_gmm_attach(false, false);
2840 f_sleep(1.0);
2841 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2842 /* try to detach to check if SGSN is still alive */
2843 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2844}
2845testcase TC_llc_null() runs on test_CT {
2846 var BSSGP_ConnHdlr vc_conn;
2847 f_init();
2848 f_sleep(1.0);
2849 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2850 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002851 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002852}
2853
Harald Welte645a1512019-04-23 23:18:23 +02002854/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2855private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2856 f_gmm_attach(false, false);
2857 f_sleep(1.0);
2858 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002859 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002860 setverdict(pass);
2861}
2862testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2863 var BSSGP_ConnHdlr vc_conn;
2864 f_init();
2865 f_sleep(1.0);
2866 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2867 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002868 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002869}
2870
2871/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2872private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2873 f_gmm_attach(false, false);
2874 f_sleep(1.0);
2875 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002876 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002877 setverdict(pass);
2878}
2879testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2880 var BSSGP_ConnHdlr vc_conn;
2881 f_init();
2882 f_sleep(1.0);
2883 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2884 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002885 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002886}
2887
Harald Welte2aaac1b2019-05-02 10:02:53 +02002888/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2889private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2890 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2891 var template (value) XID_Information xid;
2892 var template XID_Information xid_rx;
2893
2894 /* first perform regular attach */
2895 f_TC_attach(id);
2896 /* then activate PDP context */
2897 f_pdp_ctx_act(apars);
2898
2899 /* start MO XID */
2900 xid := { ts_XID_L3(''O) };
2901 xid_rx := { tr_XID_L3(''O) };
2902 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2903 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002904 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002905 [] as_xid(apars);
2906 }
2907 setverdict(pass);
2908}
2909testcase TC_xid_empty_l3() runs on test_CT {
2910 var BSSGP_ConnHdlr vc_conn;
2911 f_init();
2912 f_sleep(1.0);
2913 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2914 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002915 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002916}
2917
2918private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2919 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2920 var template (value) XID_Information xid;
2921 var template XID_Information xid_rx;
2922
2923 /* first perform regular attach */
2924 f_TC_attach(id);
2925 /* then activate PDP context */
2926 f_pdp_ctx_act(apars);
2927
2928 /* start MO XID */
2929 xid := { ts_XID_N201U(1234) };
2930 xid_rx := { tr_XID_N201U(1234) };
2931 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2932 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002933 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002934 [] as_xid(apars);
2935 }
2936 setverdict(pass);
2937}
2938testcase TC_xid_n201u() runs on test_CT {
2939 var BSSGP_ConnHdlr vc_conn;
2940 f_init();
2941 f_sleep(1.0);
2942 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2943 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002944 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002945}
2946
Alexander Couzens6bee0872019-05-11 01:48:50 +02002947private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2948 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2949
2950 /* first perform regular attach */
2951 f_TC_attach(id);
2952 /* then activate PDP context */
2953 f_pdp_ctx_act(apars);
2954 /* do a normal detach */
2955 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2956}
2957
2958testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2959 /* MS -> SGSN: Attach Request
2960 * MS <-> SGSN: [..]
2961 * MS -> SGSN: Attach Complete
2962 * MS -> SGSN: PDP Activate Request
2963 * MS <- SGSN: PDP Activate Accept
2964 * MS -> SGSN: GMM Detach Request
2965 * MS <- SGSN: GMM Detach Accept
2966 */
2967 var BSSGP_ConnHdlr vc_conn;
2968 f_init();
2969 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2970 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002971 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002972}
Harald Welte645a1512019-04-23 23:18:23 +02002973
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002974private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2975 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2976 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2977 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2978 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2979 var PDU_L3_SGSN_MS l3_mt;
2980
2981 f_send_l3(attach_req, 0);
2982
2983 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2984
2985 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2986 alt {
2987 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2988 setverdict(pass);
2989 }
2990 [] BSSGP[0].receive { repeat; }
2991 }
2992}
2993
2994/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2995 * See OS#3957 and OS#4245 for more information.
2996 */
2997testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2998 /*
2999 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
3000 * MS <-- SGSN: Identity Request (IMEI)
3001 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
3002 */
3003 var BSSGP_ConnHdlr vc_conn;
3004 f_init();
3005 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
3006 vc_conn.done;
3007 f_cleanup();
3008}
3009
Harald Welte8e5932e2020-06-17 22:12:54 +02003010private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
3011var PDU_BSSGP rx;
3012[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
3013 setverdict(fail, "Received unexpected PS PAGING: ", rx);
3014 mtc.stop;
3015 }
3016}
3017
3018/* SUSPEND, then DL traffic: should not pass + no paging expected */
3019private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
3020 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3021 var default d;
3022
3023 /* first perform regular attach */
3024 f_TC_attach(id);
3025 /* then activate PDP context */
3026 f_pdp_ctx_act(apars);
3027 /* then transceive a downlink PDU */
3028 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3029
3030 /* now suspend GPRS */
3031 f_bssgp_suspend();
3032
3033 d := activate(as_nopaging_ps());
3034
3035 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3036 * nor any related paging requests */
3037 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3038
3039 deactivate(d);
3040}
3041testcase TC_suspend_nopaging() runs on test_CT {
3042 var BSSGP_ConnHdlr vc_conn;
3043 f_init();
3044 f_sleep(1.0);
3045 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3046 vc_conn.done;
3047 f_cleanup();
3048}
3049
3050
3051/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3052private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3053 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3054 var OCT1 susp_ref;
3055 var default d;
3056
3057 /* first perform regular attach */
3058 f_TC_attach(id);
3059 /* then activate PDP context */
3060 f_pdp_ctx_act(apars);
3061 /* then transceive a downlink PDU */
3062 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3063
3064 /* now suspend GPRS */
3065 susp_ref := f_bssgp_suspend();
3066
3067 d := activate(as_nopaging_ps());
3068
3069 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3070 * nor any related paging requests */
3071 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3072
3073 deactivate(d);
3074
3075 /* resume GPRS */
3076 f_bssgp_resume(susp_ref);
3077
3078 /* now data should be flowing again */
3079 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3080}
3081testcase TC_suspend_resume() runs on test_CT {
3082 var BSSGP_ConnHdlr vc_conn;
3083 f_init();
3084 f_sleep(1.0);
3085 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3086 vc_conn.done;
3087 f_cleanup();
3088}
3089
3090/* SUSPEND, then RAU: data expected to flow after implicit resume */
3091private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3092 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3093 var default d;
3094
3095 /* first perform regular attach */
3096 f_TC_attach(id);
3097 /* then activate PDP context */
3098 f_pdp_ctx_act(apars);
3099 /* then transceive a downlink PDU */
3100 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3101
3102 /* now suspend GPRS */
3103 f_bssgp_suspend();
3104
3105 d := activate(as_nopaging_ps());
3106
3107 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3108 * nor any related paging requests */
3109 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3110
3111 deactivate(d);
3112
3113 /* perform RAU (implicit RESUME) */
3114 f_routing_area_update(g_pars.ra);
3115
Harald Welted5836dc2021-03-20 15:40:00 +01003116 /* give SGSN some time to actually receve + process the RAU Complete we sent */
3117 f_sleep(0.5);
3118
Harald Welte8e5932e2020-06-17 22:12:54 +02003119 /* now data should be flowing again */
3120 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3121
3122}
3123testcase TC_suspend_rau() runs on test_CT {
3124 var BSSGP_ConnHdlr vc_conn;
3125 f_init();
3126 f_sleep(1.0);
3127 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3128 vc_conn.done;
3129 f_cleanup();
3130}
3131
3132
3133/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3134private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3135 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3136 var default d;
3137
3138 /* first perform regular attach */
3139 f_TC_attach(id);
3140 /* then activate PDP context */
3141 f_pdp_ctx_act(apars);
3142 /* then transceive a downlink PDU */
3143 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3144
3145 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3146 f_sleep(5.0);
3147
3148 /* now data should be flowing again, but with PS PAGING */
3149 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3150 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3151
3152 /* FIXME: simulate paging response */
3153 /* FIXME: verify PDU actually arrives only after paging response was successful */
3154
3155}
3156testcase TC_paging_ps() runs on test_CT {
3157 var BSSGP_ConnHdlr vc_conn;
3158 f_init();
3159 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3160 f_sleep(1.0);
3161 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3162 vc_conn.done;
3163 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3164 f_cleanup();
3165}
3166
Philipp Maier7df55e02020-12-14 23:46:04 +01003167/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3168 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3169 * other and vice versa. */
3170testcase TC_bssgp_rim_single_report() runs on test_CT {
3171 var BSSGP_ConnHdlr vc_conn;
3172 f_init();
Philipp Maier7df55e02020-12-14 23:46:04 +01003173
3174 timer T := 2.0;
3175
3176 var template RIM_Routing_Address dst_addr;
3177 var template RIM_Routing_Address src_addr;
3178 var template RAN_Information_Request_RIM_Container req_cont;
3179 var template RAN_Information_RIM_Container res_cont;
3180 var template PDU_BSSGP bssgp_rim_pdu;
3181 var template PDU_BSSGP bssgp_rim_pdu_expect;
3182
3183 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3184 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003185
3186
Philipp Maier7df55e02020-12-14 23:46:04 +01003187 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3188 * based on the cell id in dst_addr to GB interface #1. */
3189 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3190 ts_RIM_Sequence_Number(1),
3191 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3192 ts_RIM_Protocol_Version_Number(1),
3193 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3194 omit);
3195 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3196 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3197 req_cont);
3198 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3199 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3200 tr_RAN_Information_Request_RIM_Container);
3201 RIM[0].send(bssgp_rim_pdu);
3202 T.start;
3203 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003204 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3205 setverdict(pass);
3206 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003207 [] RIM[1].receive {
3208 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003209 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003210 [] T.timeout {
3211 setverdict(fail, "No BSSGP RIM PDU received");
3212 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003213 }
3214 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003215
Philipp Maier7df55e02020-12-14 23:46:04 +01003216 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3217 * GB interface #0 */
Philipp Maier7df55e02020-12-14 23:46:04 +01003218 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3219 ts_RIM_Sequence_Number(2),
3220 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3221 ts_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003222 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si_default)),
Philipp Maier7df55e02020-12-14 23:46:04 +01003223 omit);
3224 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3225 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3226 res_cont);
3227 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3228 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3229 ?);
3230 RIM[1].send(bssgp_rim_pdu);
3231 T.start;
3232 alt {
Vadim Yanitskiy418e8062021-02-28 16:27:12 +01003233 [] RIM[0].receive(bssgp_rim_pdu_expect) {
3234 setverdict(pass);
3235 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003236 [] RIM[0].receive {
3237 setverdict(fail, "Unexpected BSSGP RIM PDU received");
Philipp Maier7df55e02020-12-14 23:46:04 +01003238 }
Vadim Yanitskiy7bc13ea2021-02-28 16:26:03 +01003239 [] T.timeout {
3240 setverdict(fail, "No BSSGP RIM PDU received");
3241 mtc.stop;
Philipp Maier7df55e02020-12-14 23:46:04 +01003242 }
3243 }
3244
3245 f_cleanup();
3246}
Harald Welte8e5932e2020-06-17 22:12:54 +02003247
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003248testcase TC_rim_eutran_to_geran() runs on test_CT {
3249 var BSSGP_ConnHdlr vc_conn;
3250 f_init();
3251 /* connect RIM related port */
3252 connect(vc_GTP:CLIENT_DEFAULT, self:GTPC);
3253
3254 var GtpPeer peer := {
3255 connId := 1,
3256 remName := mp_sgsn_gtp_ip,
3257 remPort := GTP1C_PORT
3258 }
3259
3260 var template (value) RIM_Routing_Address_GTPC gtpc_dst_addr, gtpc_src_addr;
3261 var template (value) RAN_Information_Request_RIM_Container_GTPC gtpc_rim_req_cont;
3262 var template (value) PDU_BSSGP_RAN_INFORMATION_REQUEST_GTPC gtpc_bssgp_cont;
3263 var template (value) Gtp1cUnitdata gtpc_pdu;
3264
3265 gtpc_dst_addr := t_GTPC_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3266 gtpc_src_addr := t_GTPC_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3267
3268 gtpc_rim_req_cont := ts_GTPC_RAN_Information_Request_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3269 ts_GTPC_RIM_Sequence_Number(1),
3270 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3271 ts_GTPC_RIM_Protocol_Version_Number(1),
3272 tsu_GTPC_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3273 omit);
3274 gtpc_bssgp_cont := ts_GTPC_RAN_Information_Request(ts_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3275 ts_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3276 gtpc_rim_req_cont);
3277 gtpc_pdu := ts_GTPC_RANInfoRelay(peer, ts_RANTransparentContainer_RAN_INFO_REQ(gtpc_bssgp_cont));
3278 GTPC.send(gtpc_pdu);
3279
3280 var template RIM_Routing_Address bssgp_dst_addr, bssgp_src_addr;
3281 var template PDU_BSSGP bssgp_rim_pdu_expect;
3282 bssgp_dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3283 bssgp_src_addr := t_RIM_Routing_Address_enbid(g_gb[1].cfg.bvc[0].cell_id, tac := 3, gnbid := '12345678123456'O);
3284 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3285 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3286 tr_RAN_Information_Request_RIM_Container);
3287 timer T := 2.0;
3288 T.start;
3289 alt {
3290 [] RIM[1].receive(bssgp_rim_pdu_expect) {
3291 setverdict(pass);
3292 T.stop;
3293 }
3294 [] RIM[1].receive {
3295 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3296 }
3297 [] T.timeout {
3298 setverdict(fail, "No BSSGP RIM PDU received");
3299 mtc.stop;
3300 }
3301 }
3302
3303 /* Now also emulate also the response as well and send it back on GB
3304 interface #1. Expect the result on * GTPC */
3305 var template RAN_Information_RIM_Container res_cont;
3306 var template PDU_BSSGP bssgp_rim_pdu;
3307 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3308 ts_RIM_Sequence_Number(2),
3309 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3310 ts_RIM_Protocol_Version_Number(1),
3311 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3312 omit);
3313 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, bssgp_src_addr),
3314 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bssgp_dst_addr),
3315 res_cont);
3316 RIM[1].send(bssgp_rim_pdu);
3317
3318 var template RAN_Information_RIM_Container_GTPC rim_cont;
3319 var template PDU_BSSGP_RAN_INFORMATION_GTPC gtpc_bssgp_cont_ack;
3320 var template Gtp1cUnitdata gtpc_pdu_exp;
3321 rim_cont := tr_GTPC_RAN_Information_RIM_Container(ts_GTPC_RIM_Application_Identity(RIM_APP_ID_NACC),
3322 ts_GTPC_RIM_Sequence_Number(2),
3323 ts_GTPC_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3324 ts_GTPC_RIM_Protocol_Version_Number(1),
3325 tru_GTPC_ApplContainer_or_ApplErrContainer_NACC(tru_GTPC_ApplContainer_NACC(g_gb[1].cfg.bvc[0].cell_id, false, 3, si_default)),
3326 omit);
3327 gtpc_bssgp_cont_ack := tr_GTPC_RAN_Information(tr_GTPC_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, gtpc_src_addr),
3328 tr_GTPC_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, gtpc_dst_addr),
3329 rim_cont);
3330 gtpc_pdu_exp := tr_GTPC_RANInfoRelay(peer, tr_RANTransparentContainer_RAN_INFO(gtpc_bssgp_cont_ack));
3331
3332 T.start;
3333 alt {
3334 [] GTPC.receive(gtpc_pdu_exp) {
3335 setverdict(pass);
3336 T.stop;
3337 }
3338 [] GTPC.receive {
3339 setverdict(fail, "Unexpected GTPC RIM PDU received");
3340 }
3341 [] T.timeout {
3342 setverdict(fail, "No GTPC RIM PDU received");
3343 mtc.stop;
3344 }
3345 }
3346
3347 f_cleanup();
3348}
3349
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003350/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3351private function f_TC_cell_change_different_rai_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3352 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3353
3354 /* first perform regular attach */
3355 f_gmm_attach(false, false, ran_index := 0);
3356 /* then activate PDP context */
3357 f_pdp_ctx_act(apars, ran_index := 0);
3358 /* then transceive a downlink PDU */
3359 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3360 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3361
3362 /* Now attach on different cell: */
3363 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3364 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3365 g_pars.net.expect_auth := false;
3366 f_gmm_attach(false, false, ran_index := 1, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[0]));
3367 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3368 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1, n_u := 1);
3369}
3370testcase TC_cell_change_different_rai_ci_attach() runs on test_CT {
3371 var BSSGP_ConnHdlr vc_conn;
3372 f_init();
3373 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_attach), testcasename(), g_gb, 68);
3374 vc_conn.done;
3375 f_cleanup();
3376}
3377
3378/* Test if the SGSN routes traffic to new cell after the MS attached to it */
3379/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3380private function f_TC_cell_change_different_ci_attach(charstring id) runs on BSSGP_ConnHdlr {
3381 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3382
3383 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3384 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3385
3386 /* first perform regular attach */
3387 f_gmm_attach(false, false, ran_index := 1);
3388 /* then activate PDP context */
3389 f_pdp_ctx_act(apars, ran_index := 1);
3390 /* then transceive a downlink PDU */
3391 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3392 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3393
3394 /* Now attach on different cell: */
3395 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3396 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3397 g_pars.net.expect_auth := false;
3398 f_gmm_attach(false, false, ran_index := 2, old_ra := f_cellid_to_RAI(g_pars.bssgp_cell_id[1]));
3399 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3400 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3401}
3402testcase TC_cell_change_different_ci_attach() runs on test_CT {
3403 var BSSGP_ConnHdlr vc_conn;
3404 f_init();
3405 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_attach), testcasename(), g_gb, 69);
3406 vc_conn.done;
3407 f_cleanup();
3408}
3409
3410/* Test if the SGSN silently drops MO data message coming from new BVCI if RAC changed (eg. cell change) */
3411private function f_TC_cell_change_different_rai_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3412 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3413
3414 /* first perform regular attach */
3415 f_gmm_attach(false, false, ran_index := 0);
3416 /* then activate PDP context */
3417 f_pdp_ctx_act(apars, ran_index := 0);
3418 /* then transceive a downlink PDU */
3419 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3420 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 0);
3421
3422 /* Send some data over new bvci, it should be silently discarded since
3423 * RAC changed and SGSN expects a RAU to occur in that case */
3424 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3425 var octetstring payload := f_rnd_octstring(200);
3426 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
3427 BSSGP[1].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 1));
3428 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
3429 timer T := 2.0;
3430 T.start;
3431 alt {
3432 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload)) {
3433 setverdict(fail, "Unexpected GTP message");
3434 }
3435 [] T.timeout { setverdict(pass); }
3436 }
3437
3438 /* Expect SGSN to continue routing DL data to last known NSEI+BVCI */
3439 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3440 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 0);
3441}
3442testcase TC_cell_change_different_rai_ci_data() runs on test_CT {
3443 var BSSGP_ConnHdlr vc_conn;
3444 f_init();
3445 vc_conn := f_start_handler(refers(f_TC_cell_change_different_rai_ci_data), testcasename(), g_gb, 70);
3446 vc_conn.done;
3447 f_cleanup();
3448}
3449
3450/* Test if the SGSN routes traffic to new cell after the MS switched cell without re-attaching */
3451/* Assumption: g_gb[1] and g_gb[2] configured with same RAC */
3452private function f_TC_cell_change_different_ci_data(charstring id) runs on BSSGP_ConnHdlr {
3453 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3454
3455 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[0]);
3456 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
3457
3458 /* first perform regular attach */
3459 f_gmm_attach(false, false, ran_index := 1);
3460 /* then activate PDP context */
3461 f_pdp_ctx_act(apars, ran_index := 1);
3462 /* then transceive a downlink PDU */
3463 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 1);
3464 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 1);
3465
3466 /* Now attach on different cell: */
3467 f_bssgp_client_unregister(g_pars.imsi, BSSGP_PROC[1]);
3468 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[2]);
3469
3470 f_gtpu_xceive_mo(apars, f_rnd_octstring(200), ran_index := 2, n_u := 1);
3471 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), ran_index := 2);
3472}
3473testcase TC_cell_change_different_ci_data() runs on test_CT {
3474 var BSSGP_ConnHdlr vc_conn;
3475 f_init();
3476 vc_conn := f_start_handler(refers(f_TC_cell_change_different_ci_data), testcasename(), g_gb, 71);
3477 vc_conn.done;
3478 f_cleanup();
3479}
3480
Harald Welte5ac31492018-02-15 20:39:13 +01003481control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003482 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003483 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003484 execute( TC_attach_umts_aka_umts_res() );
3485 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003486 execute( TC_attach_auth_id_timeout() );
3487 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003488 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003489 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003490 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003491 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003492 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003493 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003494 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003495 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003496 execute( TC_attach_closed_add_vty(), 20.0 );
3497 execute( TC_attach_check_subscriber_list(), 20.0 );
3498 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003499 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003500 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3501 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3502 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3503 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003504 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003505 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003506 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003507 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003508 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003509 execute( TC_detach_unknown_nopoweroff() );
3510 execute( TC_detach_unknown_poweroff() );
3511 execute( TC_detach_nopoweroff() );
3512 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003513 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003514 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003515 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003516 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003517 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003518 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003519 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003520 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003521 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003522 execute( TC_attach_restart_ctr_echo() );
3523 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003524 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003525 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3526 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003527 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003528 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003529 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003530
Harald Welte2aaac1b2019-05-02 10:02:53 +02003531 execute( TC_xid_empty_l3() );
3532 execute( TC_xid_n201u() );
3533
Harald Weltea05b8072019-04-23 22:35:05 +02003534 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003535 execute( TC_llc_sabm_dm_llgmm() );
3536 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003537
Harald Welte8e5932e2020-06-17 22:12:54 +02003538 execute( TC_suspend_nopaging() );
3539 execute( TC_suspend_resume() );
3540 execute( TC_suspend_rau() );
3541 execute( TC_paging_ps() );
3542
Philipp Maier7df55e02020-12-14 23:46:04 +01003543 execute( TC_bssgp_rim_single_report() );
Pau Espin Pedrol8c74cbb2021-05-04 15:26:56 +02003544 execute( TC_rim_eutran_to_geran() );
Philipp Maier7df55e02020-12-14 23:46:04 +01003545
Pau Espin Pedrol7c052162021-02-12 17:43:35 +01003546 execute( TC_cell_change_different_rai_ci_attach() );
3547 execute( TC_cell_change_different_rai_ci_data() );
3548 execute( TC_cell_change_different_ci_attach() );
3549 execute( TC_cell_change_different_ci_data() );
3550
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003551 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3552 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003553}
Harald Welte96a33b02018-02-04 10:36:22 +01003554
3555
3556
3557}