blob: 8e7d6e45526cfb30fb486953ce45382cd800e662 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010074 handle_sns := false,
75 nsvc := {
76 {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 21010,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1"
84 }
85 },
86 nsvci := 97
87 }
88 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020089 },
90 {
Harald Welte5e514fa2018-07-05 00:01:45 +020091 nsei := 97,
92 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010093 handle_sns := false,
94 nsvc := {
95 {
96 provider := {
97 ip := {
98 address_family := AF_INET,
99 local_udp_port := 21011,
100 local_ip := "127.0.0.1",
101 remote_udp_port := 23000,
102 remote_ip := "127.0.0.1"
103 }
104 },
105 nsvci := 98
106 }
107 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200108 },
109 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200110 nsei := 98,
111 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100112 handle_sns := false,
113 nsvc := {
114 {
115 provider := {
116 ip := {
117 address_family := AF_INET,
118 local_udp_port := 21012,
119 local_ip := "127.0.0.1",
120 remote_udp_port := 23000,
121 remote_ip := "127.0.0.1"
122 }
123 },
124 nsvci := 99
125 }
126 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200127 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200128 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200129
130 RAN_Configurations mp_ranap_cfg := {
131 {
132 transport := RANAP_TRANSPORT_IuCS,
133 sccp_service_type := "mtp3_itu",
134 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
135 own_pc := 195,
136 own_ssn := 142,
137 peer_pc := 188, /* 0.23.4 */
138 peer_ssn := 142,
139 sio := '83'O,
140 rctx := 2
141 }
142 }
Harald Welte5ac31492018-02-15 20:39:13 +0100143};
144
Harald Welte5339b2e2020-10-04 22:52:56 +0200145const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100146type record GbInstance {
147 NS_CT vc_NS,
148 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200149 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100150 BssgpConfig cfg
151};
Harald Welte96a33b02018-02-04 10:36:22 +0100152
Harald Welte2fa771f2019-05-02 20:13:53 +0200153const integer NUM_GB := 3;
154type record length(NUM_GB) of GbInstance GbInstances;
155type record length(NUM_GB) of NSConfiguration NSConfigurations;
156type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200157
Harald Welte26fbb6e2019-04-14 17:32:46 +0200158const integer NUM_RNC := 1;
159type record of RAN_Configuration RAN_Configurations;
160
Harald Welte96a33b02018-02-04 10:36:22 +0100161type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200162 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200163 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200164 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100165
Harald Welte5ac31492018-02-15 20:39:13 +0100166 var GSUP_Emulation_CT vc_GSUP;
167 var IPA_Emulation_CT vc_GSUP_IPA;
168 /* only to get events from IPA underneath GSUP */
169 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100170
Harald Welte5339b2e2020-10-04 22:52:56 +0200171 /* only needed at start to get the per-BVC references */
172 port BSSGP_CT_PROC_PT PROC;
173
Harald Welteeded9ad2018-02-17 20:57:34 +0100174 var GTP_Emulation_CT vc_GTP;
175
Harald Weltebd194722018-02-16 22:11:08 +0100176 port TELNETasp_PT SGSNVTY;
177
Harald Welte96a33b02018-02-04 10:36:22 +0100178 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200179 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100180};
181
Harald Welte26fbb6e2019-04-14 17:32:46 +0200182type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100183 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100184 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200185 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100186}
187
188type record SGSN_ConnHdlrNetworkPars {
189 boolean expect_ptmsi,
190 boolean expect_auth,
191 boolean expect_ciph
192};
193
194type record BSSGP_ConnHdlrPars {
195 /* IMEI of the simulated ME */
196 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200197 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100198 hexstring imsi,
199 /* MSISDN of the simulated MS (probably unused) */
200 hexstring msisdn,
201 /* P-TMSI allocated to the simulated MS */
202 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100203 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100204 /* TLLI of the simulated MS */
205 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100206 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100207 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200208 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200209 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
210 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100211 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100212 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200213 float t_guard,
214 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200215 SCCP_PAR_Address sccp_addr_local optional,
216 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100217};
218
Alexander Couzens89508702018-07-31 04:16:10 +0200219private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200220 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200221 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
222
223 var RoutingAreaIdentificationV ret := {
224 mccDigit1 := mcc_mnc[0],
225 mccDigit2 := mcc_mnc[1],
226 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200227 mncDigit3 := mcc_mnc[3],
228 mncDigit1 := mcc_mnc[4],
229 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200230 lac := int2oct(cell_id.ra_id.lai.lac, 16),
231 rac := int2oct(cell_id.ra_id.rac, 8)
232 }
233 return ret;
234};
235
Alexander Couzens51114d12018-07-31 18:41:56 +0200236private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
237 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
238 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100239 /* connect lower end of BSSGP emulation with NS upper port */
240 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100241
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200242 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200243 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
244 /* resolve the per-BVC component references */
245 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
246 connect(self:PROC, gb.vc_BSSGP:PROC);
247 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
248 disconnect(self:PROC, gb.vc_BSSGP:PROC);
249 }
Harald Welte5ac31492018-02-15 20:39:13 +0100250}
251
252private function f_init_gsup(charstring id) runs on test_CT {
253 id := id & "-GSUP";
254 var GsupOps ops := {
255 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
256 };
257
258 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
259 vc_GSUP := GSUP_Emulation_CT.create(id);
260
261 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
262 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
263 /* we use this hack to get events like ASP_IPA_EVENT_UP */
264 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
265
266 vc_GSUP.start(GSUP_Emulation.main(ops, id));
267 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
268
269 /* wait for incoming connection to GSUP port before proceeding */
270 timer T := 10.0;
271 T.start;
272 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700273 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100274 [] T.timeout {
275 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200276 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100277 }
278 }
279}
280
Harald Welteeded9ad2018-02-17 20:57:34 +0100281private function f_init_gtp(charstring id) runs on test_CT {
282 id := id & "-GTP";
283
284 var GtpEmulationCfg gtp_cfg := {
285 gtpc_bind_ip := mp_ggsn_ip,
286 gtpc_bind_port := GTP1C_PORT,
287 gtpu_bind_ip := mp_ggsn_ip,
288 gtpu_bind_port := GTP1U_PORT,
289 sgsn_role := false
290 };
291
292 vc_GTP := GTP_Emulation_CT.create(id);
293 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
294}
295
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200296friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100297 map(self:SGSNVTY, system:SGSNVTY);
298 f_vty_set_prompts(SGSNVTY);
299 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200300 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100301 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
302}
303
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200304private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
305 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200306 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200307 } else {
308 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
309 }
310}
311
Harald Weltebd194722018-02-16 22:11:08 +0100312
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200313/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
314function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200315 var integer i;
316
Harald Welte96a33b02018-02-04 10:36:22 +0100317 if (g_initialized == true) {
318 return;
319 }
320 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100321 g_gb[0].cfg := {
322 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200323 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200324 bvc := {
325 {
326 bvci := 196,
327 cell_id := {
328 ra_id := {
329 lai := {
330 mcc_mnc := mcc_mnc,
331 lac := 13135
332 },
333 rac := 0
334 },
335 cell_id := 20960
336 },
Harald Welte4d112c92020-11-12 19:48:31 +0100337 depth := BSSGP_DECODE_DEPTH_L3,
338 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200339 }
340 }
Harald Welte5ac31492018-02-15 20:39:13 +0100341 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200342 g_gb[1].cfg := {
343 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200344 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200345 bvc := {
346 {
347 bvci := 210,
348 cell_id := {
349 ra_id := {
350 lai := {
351 mcc_mnc := mcc_mnc,
352 lac := 13200
353 },
354 rac := 0
355 },
356 cell_id := 20961
357 },
Harald Welte4d112c92020-11-12 19:48:31 +0100358 depth := BSSGP_DECODE_DEPTH_L3,
359 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200360 }
361 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200362 };
363 g_gb[2].cfg := {
364 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200365 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200366 bvc := {
367 {
368 bvci := 220,
369 cell_id := {
370 ra_id := {
371 lai := {
372 mcc_mnc := mcc_mnc,
373 lac := 13300
374 },
375 rac := 0
376 },
377 cell_id := 20962
378 },
Harald Welte4d112c92020-11-12 19:48:31 +0100379 depth := BSSGP_DECODE_DEPTH_L3,
380 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200381 }
382 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200383 };
Harald Welte96a33b02018-02-04 10:36:22 +0100384
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200385 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200386 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
387 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
388 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200389
Alexander Couzens1552e792019-07-23 20:38:39 +0200390 if (g_ranap_enable) {
391 for (i := 0; i < NUM_RNC; i := i+1) {
392 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
393 f_ran_adapter_start(g_ranap[i]);
394 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200395 }
Harald Welte5ac31492018-02-15 20:39:13 +0100396 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100397 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200398 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100399}
Harald Welte96a33b02018-02-04 10:36:22 +0100400
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200401function f_cleanup() runs on test_CT {
402 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200403 if (g_ranap_enable) {
404 for (i := 0; i < NUM_RNC; i := i+1) {
405 f_ran_adapter_cleanup(g_ranap[i]);
406 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200407 }
408 self.stop;
409}
410
Harald Welte26fbb6e2019-04-14 17:32:46 +0200411private function RncUnitdataCallback(RANAP_PDU ranap)
412runs on RAN_Emulation_CT return template RANAP_PDU {
413 var template RANAP_PDU resp := omit;
414
415 log ("RANAP_RncUnitDataCallback");
416 /* answer all RESET with RESET ACK */
417 if (match(ranap, tr_RANAP_Reset)) {
418 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
419 var CN_DomainIndicator dom;
420 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
421 resp := ts_RANAP_ResetAck(dom);
422 }
423 return resp;
424}
425
426const RanOps RNC_RanOps := {
427 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
428 ranap_unitdata_cb := refers(RncUnitdataCallback),
429 ps_domain := true,
430 decode_dtap := true,
431 role_ms := true,
432 protocol := RAN_PROTOCOL_RANAP,
433 transport := RANAP_TRANSPORT_IuCS,
434 use_osmux := false,
435 sccp_addr_local := omit,
436 sccp_addr_peer := omit
437};
438
Harald Welte5ac31492018-02-15 20:39:13 +0100439type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
440
441/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200442function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100443 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100444runs on test_CT return BSSGP_ConnHdlr {
445 var BSSGP_ConnHdlr vc_conn;
446 var SGSN_ConnHdlrNetworkPars net_pars := {
447 expect_ptmsi := true,
448 expect_auth := true,
449 expect_ciph := false
450 };
451 var BSSGP_ConnHdlrPars pars := {
452 imei := f_gen_imei(imsi_suffix),
453 imsi := f_gen_imsi(imsi_suffix),
454 msisdn := f_gen_msisdn(imsi_suffix),
455 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100456 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100457 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100458 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100459 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200460 bssgp_cell_id := {
461 gb[0].cfg.bvc[0].cell_id,
462 gb[1].cfg.bvc[0].cell_id,
463 gb[2].cfg.bvc[0].cell_id
464 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200465 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100466 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100467 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200468 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200469 sccp_addr_local := omit,
470 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100471 };
472
Alexander Couzens1552e792019-07-23 20:38:39 +0200473 if (g_ranap_enable) {
474 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
475 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
476 }
477
Harald Welte5ac31492018-02-15 20:39:13 +0100478 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200479
480 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
481 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
482 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100483 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200484
485 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
486 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
487 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100488 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200489
490 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
491 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
492 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100493 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100494
Harald Welte26fbb6e2019-04-14 17:32:46 +0200495 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200496 if (g_ranap_enable) {
497 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
498 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
499 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200500
Harald Welte5ac31492018-02-15 20:39:13 +0100501 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
502 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
503
Harald Welteeded9ad2018-02-17 20:57:34 +0100504 connect(vc_conn:GTP, vc_GTP:CLIENT);
505 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
506
Harald Welte5ac31492018-02-15 20:39:13 +0100507 vc_conn.start(f_handler_init(fn, id, pars));
508 return vc_conn;
509}
510
Harald Welte62e29582018-02-16 21:17:11 +0100511private altstep as_Tguard() runs on BSSGP_ConnHdlr {
512 [] g_Tguard.timeout {
513 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200514 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100515 }
516}
517
Harald Welte5ac31492018-02-15 20:39:13 +0100518/* first function called in every ConnHdlr */
519private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
520runs on BSSGP_ConnHdlr {
521 /* do some common stuff like setting up g_pars */
522 g_pars := pars;
523
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200524 llc := f_llc_create(false);
525
Harald Welte5ac31492018-02-15 20:39:13 +0100526 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200527 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100528 /* tell GSUP dispatcher to send this IMSI to us */
529 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100530 /* tell GTP dispatcher to send this IMSI to us */
531 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100532
Harald Welte62e29582018-02-16 21:17:11 +0100533 g_Tguard.start(pars.t_guard);
534 activate(as_Tguard());
535
Harald Welte5ac31492018-02-15 20:39:13 +0100536 /* call the user-supplied test case function */
537 fn.apply(id);
538 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100539}
540
541/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100542 * Detach without Attach
543 * SM procedures without attach / RAU
544 * ATTACH / RAU
545 ** with / without authentication
546 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100547 * re-transmissions of LLC frames
548 * PDP Context activation
549 ** with different GGSN config in SGSN VTY
550 ** with different PDP context type (v4/v6/v46)
551 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100552 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100553 */
554
555testcase TC_wait_ns_up() runs on test_CT {
556 f_init();
557 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200558 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100559}
560
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200561friend function is_gb(integer ran_index) return boolean {
562 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200563}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200564friend function is_iu(integer ran_index) return boolean {
565 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200566}
567
Alexander Couzens0507ec32019-09-15 22:41:22 +0200568function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200569 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200570 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 +0200571}
572
Alexander Couzens0507ec32019-09-15 22:41:22 +0200573private 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 +0200574 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
575 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
576 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200577 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200578}
579
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200580/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
581function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
582 log("Sending InitialUE: ", l3_mo);
583 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
584 var RANAP_PDU ranap;
585 var LAI lai := {
586 pLMNidentity := '62F224'O,
587 lAC := '1234'O,
588 iE_Extensions := omit
589 };
590 var SAI sai := {
591 pLMNidentity := lai.pLMNidentity,
592 lAC := lai.lAC,
593 sAC := '0000'O, /* FIXME */
594 iE_Extensions := omit
595 };
596 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
597 var GlobalRNC_ID grnc_id := {
598 pLMNidentity := lai.pLMNidentity,
599 rNC_ID := 2342 /* FIXME */
600 };
601
602 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
603 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
604 alt {
605 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
606 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
607 setverdict(fail, "DISC.ind from SCCP");
608 mtc.stop;
609 }
610 }
611}
612
613/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200614function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
615 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200616 if (g_pars.rnc_send_initial_ue) {
617 g_pars.rnc_send_initial_ue := false;
618 f_send_l3_initial_ue(l3_mo);
619 } else {
620 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
621 }
622 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200623 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200624 }
625}
626
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200627altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700628 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200629 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100630 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200631 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100632 repeat;
633 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200634 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200635 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200636 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200637 repeat;
638 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200639 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100640 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200641 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200642 repeat;
643 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200644 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200645 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200646 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100647 repeat;
648 }
649}
Harald Welte96a33b02018-02-04 10:36:22 +0100650
Harald Welteca362462019-05-02 20:11:21 +0200651/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200652function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200653runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200654 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200655 var PDU_L3_SGSN_MS l3_mt;
656 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200657 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
658 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200659 l3_mt := mt.dtap;
660 }
Harald Welteca362462019-05-02 20:11:21 +0200661 }
662 return l3_mt;
663}
664
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200665/* perform GMM authentication (if expected).
666 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
667 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200668function 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 +0100669 var PDU_L3_MS_SGSN l3_mo;
670 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200671 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100672 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200673 var GSUP_IE auth_tuple;
674 var template AuthenticationParameterAUTNTLV autn;
675
676 if (umts_aka_challenge) {
677 g_pars.vec := f_gen_auth_vec_3g();
678 autn := {
679 elementIdentifier := '28'O,
680 lengthIndicator := lengthof(g_pars.vec.autn),
681 autnValue := g_pars.vec.autn
682 };
683
684 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
685 g_pars.vec.sres,
686 g_pars.vec.kc,
687 g_pars.vec.ik,
688 g_pars.vec.ck,
689 g_pars.vec.autn,
690 g_pars.vec.res));
691 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
692 } else {
693 g_pars.vec := f_gen_auth_vec_2g();
694 autn := omit;
695 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
696 g_pars.vec.sres,
697 g_pars.vec.kc));
698 log("GSUP sends only 2G auth tuple", auth_tuple);
699 }
Harald Welteca362462019-05-02 20:11:21 +0200700
Harald Welte5ac31492018-02-15 20:39:13 +0100701 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
702 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200703
704 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
705 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200706 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100707 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200708 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
709
710 if (umts_aka_challenge and not force_gsm_sres) {
711 /* set UMTS response instead */
712 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
713 valueField := substr(g_pars.vec.res, 0, 4)
714 };
715 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
716 elementIdentifier := '21'O,
717 lengthIndicator := lengthof(g_pars.vec.res) - 4,
718 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
719 };
720 }
721
722 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100723 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
724 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
725 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
726 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
727 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200728 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200729
730 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200731 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200732 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
733 key_sts := ?)) {
734 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
735 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200736 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200737 }
738 }
Harald Welte76dee092018-02-16 22:12:59 +0100739 } else {
740 /* wait for identity procedure */
741 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100742 }
Harald Welte76dee092018-02-16 22:12:59 +0100743
Harald Welte5ac31492018-02-15 20:39:13 +0100744 deactivate(di);
745}
746
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200747function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100748 g_pars.p_tmsi := p_tmsi;
749 /* update TLLI */
750 g_pars.tlli_old := g_pars.tlli;
751 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100752 if (is_gb(ran_index)) {
753 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
754 }
Harald Weltef70997d2018-02-17 10:11:19 +0100755}
756
Harald Welte04683d02018-02-16 22:43:45 +0100757function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
758 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100759 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200760 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100761 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200762 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200763 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100764 }
Harald Welte04683d02018-02-16 22:43:45 +0100765 g_pars.ra := aa.routingAreaIdentification;
766 if (ispresent(aa.allocatedPTMSI)) {
767 if (not g_pars.net.expect_ptmsi) {
768 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200769 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100770 }
Harald Weltef70997d2018-02-17 10:11:19 +0100771 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100772 }
773 if (ispresent(aa.msIdentity)) {
774 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200775 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100776 }
777 /* P-TMSI.sig */
778 if (ispresent(aa.ptmsiSignature)) {
779 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
780 }
781 /* updateTimer */
782 // aa.readyTimer
783 /* T3302, T3319, T3323, T3312_ext, T3324 */
784}
785
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200786function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100787 /* mandatory IE */
788 g_pars.ra := ra.routingAreaId;
789 if (ispresent(ra.allocatedPTMSI)) {
790 if (not g_pars.net.expect_ptmsi) {
791 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200792 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100793 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200794 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100795 }
796 if (ispresent(ra.msIdentity)) {
797 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200798 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100799 }
800 /* P-TMSI.sig */
801 if (ispresent(ra.ptmsiSignature)) {
802 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
803 }
804 /* updateTimer */
805 // aa.readyTimer
806 /* T3302, T3319, T3323, T3312_ext, T3324 */
807}
808
809
Harald Welte5a4fa042018-02-16 20:59:21 +0100810function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
811 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
812}
813
Harald Welte23178c52018-02-17 09:36:33 +0100814/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700815private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100816 if (ispresent(g_pars.p_tmsi)) {
817 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
818 } else {
819 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
820 }
821}
822
Harald Welte311ec272018-02-17 09:40:03 +0100823private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100824 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100825 /* Expect MSC to perform LU with HLR */
826 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100827 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
828 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
829 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100830 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
831 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
832}
833
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200834friend function f_gmm_attach(boolean umts_aka_challenge, boolean force_gsm_sres, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte5a4fa042018-02-16 20:59:21 +0100835 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200836 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
Harald Welteca362462019-05-02 20:11:21 +0200837 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100838
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200839 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
840 * 3G auth vectors */
841 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
842 /* The thing is, if the solSACapability is 'omit', then the
843 * revisionLevelIndicatior is at the wrong place! */
844 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
845
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200846 f_send_l3(attach_req, ran_index);
847 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200848 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100849 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100850
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200851 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200852 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
853
Harald Welte04683d02018-02-16 22:43:45 +0100854 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200855 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200856
857 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200858 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200859 as_iu_release_compl_disc();
860 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200861
862 /* Race condition
863 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
864 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
865 * arrived before it. This results in a test case failure.
866 * Delay execution by 50 ms
867 */
868 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200869}
870
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200871friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
872 timer T := 5.0;
873 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100874 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 +0200875 T.start;
876 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100877 [] 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 +0200878 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
879 }
Harald Welte9b461a92020-12-10 23:41:14 +0100880 [] 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 +0200881 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
882 mtc.stop;
883 }
884 [] T.timeout {
885 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
886 mtc.stop;
887 }
888 }
889 return '00'O;
890}
891
892friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
893 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100894 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 +0200895 T.start;
896 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100897 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
898 [] 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 +0200899?)) {
900 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
901 mtc.stop;
902 }
903 [] T.timeout {
904 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
905 mtc.stop;
906 }
907 }
908}
909
910
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200911private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
912 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100913 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100914}
915
916testcase TC_attach() runs on test_CT {
917 var BSSGP_ConnHdlr vc_conn;
918 f_init();
919 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200920 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100921 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200922 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100923}
924
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100925testcase TC_attach_mnc3() runs on test_CT {
926 var BSSGP_ConnHdlr vc_conn;
927 f_init('023042'H);
928 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200929 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100930 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200931 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100932}
933
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200934private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
935 f_gmm_attach(true, false);
936 setverdict(pass);
937}
938testcase TC_attach_umts_aka_umts_res() runs on test_CT {
939 var BSSGP_ConnHdlr vc_conn;
940 f_init();
941 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200942 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200943 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200944 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200945}
946
947private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
948 f_gmm_attach(true, true);
949 setverdict(pass);
950}
951testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
952 var BSSGP_ConnHdlr vc_conn;
953 f_init();
954 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200955 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200956 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200957 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200958}
959
Harald Welte5b7c8122018-02-16 21:48:17 +0100960/* MS never responds to ID REQ, expect ATTACH REJECT */
961private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100962 var RoutingAreaIdentificationV old_ra := f_random_RAI();
963
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200964 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100965 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200966 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100967 /* don't send ID Response */
968 repeat;
969 }
Harald Welte955aa942019-05-03 01:29:29 +0200970 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100971 setverdict(pass);
972 }
Harald Welte955aa942019-05-03 01:29:29 +0200973 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100974 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200975 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100976 }
977 }
978}
979testcase TC_attach_auth_id_timeout() runs on test_CT {
980 var BSSGP_ConnHdlr vc_conn;
981 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200982 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 +0100983 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200984 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100985}
986
987/* HLR never responds to SAI REQ, expect ATTACH REJECT */
988private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100989 var RoutingAreaIdentificationV old_ra := f_random_RAI();
990
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200991 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100992 alt {
993 [] as_mm_identity();
994 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
995 }
996 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200997 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100998 setverdict(pass);
999}
1000testcase TC_attach_auth_sai_timeout() runs on test_CT {
1001 var BSSGP_ConnHdlr vc_conn;
1002 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001003 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001004 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001005 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001006}
1007
Harald Weltefe253882018-02-17 09:25:00 +01001008/* HLR rejects SAI, expect ATTACH REJECT */
1009private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001010 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1011
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001012 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001013 alt {
1014 [] as_mm_identity();
1015 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1016 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1017 }
1018 }
Harald Welte955aa942019-05-03 01:29:29 +02001019 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001020 setverdict(pass);
1021}
1022testcase TC_attach_auth_sai_reject() runs on test_CT {
1023 var BSSGP_ConnHdlr vc_conn;
1024 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001025 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001026 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001027 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001028}
1029
Harald Welte5b7c8122018-02-16 21:48:17 +01001030/* HLR never responds to UL REQ, expect ATTACH REJECT */
1031private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001032 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001033 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1034
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001035 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001036 f_gmm_auth();
1037 /* Expect MSC to perform LU with HLR */
1038 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1039 /* Never follow-up with ISD_REQ or UL_RES */
1040 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001041 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001042 setverdict(pass);
1043 }
Harald Welte955aa942019-05-03 01:29:29 +02001044 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1045 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001046 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001047 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001048 }
1049 }
1050}
1051testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1052 var BSSGP_ConnHdlr vc_conn;
1053 f_init();
1054 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001055 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001056 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001057 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001058}
1059
Harald Welteb7c14e92018-02-17 09:29:16 +01001060/* HLR rejects UL REQ, expect ATTACH REJECT */
1061private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001062 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001063 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1064
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001065 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001066 f_gmm_auth();
1067 /* Expect MSC to perform LU with HLR */
1068 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1069 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1070 }
1071 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001072 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +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 Welteb7c14e92018-02-17 09:29:16 +01001077 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001078 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001079 }
1080 }
1081}
1082testcase TC_attach_gsup_lu_reject() 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_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001087 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001088 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001089}
1090
1091
Harald Welte3823e2e2018-02-16 21:53:48 +01001092/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1093private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001094 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001095 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1096
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001097 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001098 f_gmm_auth();
1099 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001100 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001101
Harald Welte955aa942019-05-03 01:29:29 +02001102 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1103 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001104 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001105 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001106 setverdict(pass);
1107}
Harald Welte3823e2e2018-02-16 21:53:48 +01001108testcase TC_attach_combined() runs on test_CT {
1109 var BSSGP_ConnHdlr vc_conn;
1110 f_init();
1111 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001112 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001113 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001114 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001115}
1116
Harald Welte76dee092018-02-16 22:12:59 +01001117/* Attempt of GPRS ATTACH in 'accept all' mode */
1118private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001119 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001120 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1121
1122 g_pars.net.expect_auth := false;
1123
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001124 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001125 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001126 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1127 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001128 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001129 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001130 setverdict(pass);
1131}
1132testcase TC_attach_accept_all() runs on test_CT {
1133 var BSSGP_ConnHdlr vc_conn;
1134 f_init();
1135 f_sleep(1.0);
1136 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001137 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001138 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001139 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001140}
Harald Welte5b7c8122018-02-16 21:48:17 +01001141
Harald Welteb2124b22018-02-16 22:26:56 +01001142/* Attempt of GPRS ATTACH in 'accept all' mode */
1143private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001144 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1145
1146 /* Simulate a foreign IMSI */
1147 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001148 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001149
1150 g_pars.net.expect_auth := false;
1151
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001152 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001153 alt {
1154 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001155 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001156 setverdict(pass);
1157 }
Harald Welte955aa942019-05-03 01:29:29 +02001158 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001159 setverdict(pass);
1160 }
Harald Welte955aa942019-05-03 01:29:29 +02001161 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001162 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001163 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001164 }
Harald Welteb2124b22018-02-16 22:26:56 +01001165 }
1166}
1167testcase TC_attach_closed() runs on test_CT {
1168 var BSSGP_ConnHdlr vc_conn;
1169 f_init();
1170 f_sleep(1.0);
1171 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1172 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001173 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001174 vc_conn.done;
1175 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001176 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001177 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001178 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001179}
1180
Harald Welte04683d02018-02-16 22:43:45 +01001181/* Routing Area Update from Unknown TLLI -> REJECT */
1182private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001183 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1184
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001185 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 +01001186 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001187 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001188 setverdict(pass);
1189 }
1190 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001191 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001192 }
1193}
1194testcase TC_rau_unknown() runs on test_CT {
1195 var BSSGP_ConnHdlr vc_conn;
1196 f_init();
1197 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001198 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001199 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001200 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001201}
1202
Harald Welte91636de2018-02-17 10:16:14 +01001203private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001204 /* first perform regular attach */
1205 f_TC_attach(id);
1206
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001207 f_routing_area_update(g_pars.ra);
1208
Harald Welte91636de2018-02-17 10:16:14 +01001209}
1210testcase TC_attach_rau() runs on test_CT {
1211 var BSSGP_ConnHdlr vc_conn;
1212 f_init();
1213 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001214 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001215 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001216 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001217}
Harald Welte04683d02018-02-16 22:43:45 +01001218
Harald Welte6abb9fe2018-02-17 15:24:48 +01001219/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001220function 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 +02001221 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001222 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001223 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001224 if (expect_purge) {
1225 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1226 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1227 }
1228 T.start;
1229 alt {
1230 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1231 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001232 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001233 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001234 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001235 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001236 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001237 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001238 /* TODO: check if any PDP contexts are deactivated on network side? */
1239 }
1240 [power_off] T.timeout {
1241 setverdict(pass);
1242 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001243 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001244 g_pars.ra := omit;
1245 setverdict(pass);
1246 /* TODO: check if any PDP contexts are deactivated on network side? */
1247 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001248 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001249 if (power_off) {
1250 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1251 } else {
1252 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1253 }
1254 mtc.stop;
1255 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001256 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001257 }
1258}
1259
1260/* IMSI DETACH (non-power-off) for unknown TLLI */
1261private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1262 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1263}
1264testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1265 var BSSGP_ConnHdlr vc_conn;
1266 f_init();
1267 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001268 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001269 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001270 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001271}
1272
1273/* IMSI DETACH (power-off) for unknown TLLI */
1274private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1275 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1276}
1277testcase TC_detach_unknown_poweroff() runs on test_CT {
1278 var BSSGP_ConnHdlr vc_conn;
1279 f_init();
1280 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001281 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001282 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001283 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001284}
1285
1286/* IMSI DETACH (non-power-off) for known TLLI */
1287private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1288 /* first perform regular attach */
1289 f_TC_attach(id);
1290
1291 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1292}
1293testcase TC_detach_nopoweroff() runs on test_CT {
1294 var BSSGP_ConnHdlr vc_conn;
1295 f_init();
1296 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001297 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001298 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001299 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001300}
1301
1302/* IMSI DETACH (power-off) for known TLLI */
1303private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1304 /* first perform regular attach */
1305 f_TC_attach(id);
1306
1307 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1308}
1309testcase TC_detach_poweroff() runs on test_CT {
1310 var BSSGP_ConnHdlr vc_conn;
1311 f_init();
1312 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001313 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001314 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001315 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001316}
1317
Harald Welteeded9ad2018-02-17 20:57:34 +01001318type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001319 BIT3 tid, /* L3 Transaction ID */
1320 BIT4 nsapi, /* SNDCP NSAPI */
1321 BIT4 sapi, /* LLC SAPI */
1322 QoSV qos, /* QoS parameters */
1323 PDPAddressV addr, /* IP address */
1324 octetstring apn optional, /* APN name */
1325 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1326 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001327 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001328 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001329
Harald Welte822f9102018-02-18 20:39:06 +01001330 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1331 OCT4 ggsn_tei_u, /* GGSN TEI User */
1332 octetstring ggsn_ip_c, /* GGSN IP Control */
1333 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001334 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001335
Harald Welte822f9102018-02-18 20:39:06 +01001336 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1337 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1338 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1339 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001340};
1341
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001342
1343private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1344 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1345 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1346 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1347 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1348 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1349 f_gtp_register_teid(apars.ggsn_tei_c);
1350 f_gtp_register_teid(apars.ggsn_tei_u);
1351}
1352
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001353function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001354runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001355 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1356 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001357 var template Recovery_gtpc recovery := omit;
1358
1359 if (send_recovery) {
1360 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1361 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001362
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001363 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 +02001364 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001365 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1366 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1367 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1368 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1369 apars.sgsn_tei_c, apars.gtp_resp_cause,
1370 apars.ggsn_tei_c, apars.ggsn_tei_u,
1371 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001372 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1373 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001374 }
1375 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001376 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001377 setverdict(pass);
1378 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001379 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001380 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001381 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001382 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001383 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001384 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001385 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001386 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001387 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001388 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1389 mtc.stop;
1390 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001391 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001392 setverdict(pass);
1393 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001394 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001395 }
1396}
1397
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001398function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001399runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001400 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1401 var Gtp1cUnitdata g_ud;
1402
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001403 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001404 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1405 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001406 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001407 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1408 }
1409 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001410 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001411 setverdict(pass);
1412 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001413 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001414 }
1415}
1416
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001417function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001418runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001419 var Gtp1cUnitdata g_ud;
1420 var integer seq_nr := 23;
1421 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1422
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001423 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001424 if (error_ind) {
1425 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1426 } else {
1427 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1428 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001429
1430 timer T := 5.0;
1431 T.start;
1432
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001433 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001434 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1435 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001436 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001437 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1438 repeat;
1439 }
1440 [] T.timeout {
1441 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1442 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001443 }
1444}
1445
Harald Welte6f203162018-02-18 22:04:55 +01001446
Harald Welteeded9ad2018-02-17 20:57:34 +01001447/* Table 10.5.156/3GPP TS 24.008 */
1448template (value) QoSV t_QosDefault := {
1449 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1450 delayClass := '100'B, /* best effort */
1451 spare1 := '00'B,
1452 precedenceClass := '010'B, /* normal */
1453 spare2 := '0'B,
1454 peakThroughput := '0000'B, /* subscribed */
1455 meanThroughput := '00000'B, /* subscribed */
1456 spare3 := '000'B,
1457 deliverErroneusSDU := omit,
1458 deliveryOrder := omit,
1459 trafficClass := omit,
1460 maxSDUSize := omit,
1461 maxBitrateUplink := omit,
1462 maxBitrateDownlink := omit,
1463 sduErrorRatio := omit,
1464 residualBER := omit,
1465 trafficHandlingPriority := omit,
1466 transferDelay := omit,
1467 guaranteedBitRateUplink := omit,
1468 guaranteedBitRateDownlink := omit,
1469 sourceStatisticsDescriptor := omit,
1470 signallingIndication := omit,
1471 spare4 := omit,
1472 maxBitrateDownlinkExt := omit,
1473 guaranteedBitRateDownlinkExt := omit,
1474 maxBitrateUplinkExt := omit,
1475 guaranteedBitRateUplinkExt := omit,
1476 maxBitrateDownlinkExt2 := omit,
1477 guaranteedBitRateDownlinkExt2 := omit,
1478 maxBitrateUplinkExt2 := omit,
1479 guaranteedBitRateUplinkExt2 := omit
1480}
1481
1482/* 10.5.6.4 / 3GPP TS 24.008 */
1483template (value) PDPAddressV t_AddrIPv4dyn := {
1484 pdpTypeOrg := '0001'B, /* IETF */
1485 spare := '0000'B,
1486 pdpTypeNum := '21'O, /* IPv4 */
1487 addressInfo := omit
1488}
1489template (value) PDPAddressV t_AddrIPv6dyn := {
1490 pdpTypeOrg := '0001'B, /* IETF */
1491 spare := '0000'B,
1492 pdpTypeNum := '53'O, /* IPv6 */
1493 addressInfo := omit
1494}
1495
Harald Welte37692d82018-02-18 15:21:34 +01001496template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001497 tid := '000'B,
1498 nsapi := '0101'B, /* < 5 are reserved */
1499 sapi := '0011'B, /* 3/5/9/11 */
1500 qos := t_QosDefault,
1501 addr := t_AddrIPv4dyn,
1502 apn := omit,
1503 pco := omit,
1504 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001505 gtp_resp_cause := int2oct(128, 1),
1506 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001507
1508 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001509 ggsn_tei_c := f_rnd_octstring(4),
1510 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001511 ggsn_ip_c := f_inet_addr(ggsn_ip),
1512 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001513 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001514
Harald Welteeded9ad2018-02-17 20:57:34 +01001515 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001516 sgsn_tei_u := omit,
1517 sgsn_ip_c := omit,
1518 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001519}
1520
Harald Welte37692d82018-02-18 15:21:34 +01001521template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1522 connId := 1,
1523 remName := f_inet_ntoa(ip),
1524 remPort := GTP1U_PORT
1525}
1526
1527template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1528 connId := 1,
1529 remName := f_inet_ntoa(ip),
1530 remPort := GTP1C_PORT
1531}
1532
1533private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1534 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1535 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1536}
1537
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001538private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1539 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001540 repeat;
1541 }
1542}
1543
1544template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1545 pDU_SN_UNITDATA := {
1546 nsapi := nsapi,
1547 moreBit := ?,
1548 snPduType := '1'B,
1549 firstSegmentIndicator := ?,
1550 spareBit := ?,
1551 pcomp := ?,
1552 dcomp := ?,
1553 npduNumber := ?,
1554 segmentNumber := ?,
1555 npduNumberContinued := ?,
1556 dataSegmentSnUnitdataPdu := payload
1557 }
1558}
1559
1560/* simple case: single segment, no compression */
1561template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1562 pDU_SN_UNITDATA := {
1563 nsapi := nsapi,
1564 moreBit := '0'B,
1565 snPduType := '1'B,
1566 firstSegmentIndicator := '1'B,
1567 spareBit := '0'B,
1568 pcomp := '0000'B,
1569 dcomp := '0000'B,
1570 npduNumber := '0000'B,
1571 segmentNumber := '0000'B,
1572 npduNumberContinued := '00'O,
1573 dataSegmentSnUnitdataPdu := payload
1574 }
1575}
1576
1577/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001578private 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 +02001579runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001580 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001581 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1582 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001583 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001584 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1585 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001586 [] as_xid(apars, ran_index);
1587 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001588 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1589 [expect_fwd] T.timeout {
1590 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1591 mtc.stop;
1592 }
1593 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1594 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1595 mtc.stop;
1596 }
1597 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001598 }
1599}
1600
Harald Welte64d6b512020-06-17 16:42:00 +02001601/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001602private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001603runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001604 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1605 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1606 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001607 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001608 /* Expect PDU via GTP from SGSN on simulated GGSN */
1609 alt {
1610 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1611 }
1612}
1613
Harald Welteeded9ad2018-02-17 20:57:34 +01001614private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001615 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001616
1617 /* first perform regular attach */
1618 f_TC_attach(id);
1619
1620 f_pdp_ctx_act(apars);
1621}
1622testcase TC_attach_pdp_act() runs on test_CT {
1623 var BSSGP_ConnHdlr vc_conn;
1624 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001625 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001626 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001627 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001628}
Harald Welteb2124b22018-02-16 22:26:56 +01001629
Harald Welte835b15f2018-02-18 14:39:11 +01001630/* PDP Context activation for not-attached subscriber; expect fail */
1631private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001632 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001633 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 +01001634 apars.apn, apars.pco));
1635 alt {
1636 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001637 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001638 setverdict(pass);
1639 }
1640 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1641 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001642 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001643 }
Harald Welte955aa942019-05-03 01:29:29 +02001644 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001645 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001646 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001647 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001648 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001649 }
1650}
1651testcase TC_pdp_act_unattached() runs on test_CT {
1652 var BSSGP_ConnHdlr vc_conn;
1653 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001654 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001655 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001656 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001657}
1658
Harald Welte37692d82018-02-18 15:21:34 +01001659/* ATTACH + PDP CTX ACT + user plane traffic */
1660private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1661 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1662
1663 /* first perform regular attach */
1664 f_TC_attach(id);
1665 /* then activate PDP context */
1666 f_pdp_ctx_act(apars);
1667 /* then transceive a downlink PDU */
1668 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1669 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1670}
1671testcase TC_attach_pdp_act_user() runs on test_CT {
1672 var BSSGP_ConnHdlr vc_conn;
1673 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001674 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001675 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001676 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001677}
1678
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001679/* ATTACH + PDP CTX ACT; reject from GGSN */
1680private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1681 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1682
1683 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1684 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1685
1686 /* first perform regular attach */
1687 f_TC_attach(id);
1688 /* then activate PDP context */
1689 f_pdp_ctx_act(apars);
1690}
1691testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1692 var BSSGP_ConnHdlr vc_conn;
1693 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001694 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001695 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001696 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001697}
Harald Welte835b15f2018-02-18 14:39:11 +01001698
Harald Welte6f203162018-02-18 22:04:55 +01001699/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1700private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1701 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1702
1703 /* first perform regular attach */
1704 f_TC_attach(id);
1705 /* then activate PDP context */
1706 f_pdp_ctx_act(apars);
1707 /* then transceive a downlink PDU */
1708 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1709 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1710
1711 f_pdp_ctx_deact_mo(apars, '00'O);
1712}
1713testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1714 var BSSGP_ConnHdlr vc_conn;
1715 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001716 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 +01001717 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001718 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001719}
1720
Harald Welte57b9b7f2018-02-18 22:28:13 +01001721/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1722private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1723 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1724
1725 /* first perform regular attach */
1726 f_TC_attach(id);
1727 /* then activate PDP context */
1728 f_pdp_ctx_act(apars);
1729 /* then transceive a downlink PDU */
1730 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1731 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1732
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001733 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001734}
1735testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1736 var BSSGP_ConnHdlr vc_conn;
1737 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001738 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 +01001739 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001740 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001741}
1742
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001743/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1744private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1745 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1746 var Gtp1cUnitdata g_ud;
1747 var integer i;
1748 var OCT1 cause_regular_deact := '24'O;
1749
1750 /* first perform regular attach + PDP context act */
1751 f_TC_attach(id);
1752 f_pdp_ctx_act(apars);
1753
1754 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1755 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1756
1757 for (i := 0; i < 2; i := i+1) {
1758 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1759 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1760 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1761 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1762 }
1763 }
1764
1765 alt {
1766 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1767 setverdict(pass);
1768 }
1769 [] as_xid(apars, 0);
1770 }
1771
1772 /* Make sure second DeactPdpAccept is sent: */
1773 timer T := 2.0;
1774 T.start;
1775 alt {
1776 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1777 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1778 }
1779 [] T.timeout {
1780 setverdict(pass);
1781 }
1782 }
1783
1784 setverdict(pass);
1785}
1786testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1787 var BSSGP_ConnHdlr vc_conn;
1788 f_init();
1789 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1790 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001791 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001792}
1793
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001794/* ATTACH + ATTACH (2nd) */
1795private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1796 g_pars.t_guard := 5.0;
1797
1798 /* first perform regular attach */
1799 f_TC_attach(id);
1800
1801 /* second to perform regular attach */
1802 f_TC_attach(id);
1803}
1804
1805
1806testcase TC_attach_second_attempt() runs on test_CT {
1807 var BSSGP_ConnHdlr vc_conn;
1808 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001809 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001810 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001811 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001812}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001813
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001814private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1815 var Gtp1cUnitdata g_ud;
1816 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1817 var integer seq_nr;
1818
1819 /* first perform regular attach */
1820 f_TC_attach(id);
1821 /* then activate PDP context */
1822 f_pdp_ctx_act(apars);
1823
1824 /* Wait to receive first echo request and send initial Restart counter */
1825 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1826 BSSGP[0].clear;
1827 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1828 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1829 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1830 }
1831
1832 /* At some point next echo request not answered will timeout and SGSN
1833 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1834 timer T := 3.0 * 6.0 + 16.0;
1835 T.start;
1836 alt {
1837 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1838 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1839 setverdict(pass);
1840 }
1841 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1842 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1843 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1844 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1845 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1846 repeat;
1847 }
1848 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1849 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1850 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1851 repeat;
1852 }
1853 [] T.timeout {
1854 setverdict(fail, "BSSGP DeactPdpReq not received");
1855 mtc.stop;
1856 }
1857 [] as_xid(apars);
1858 }
1859 T.stop
1860
1861 setverdict(pass);
1862}
1863/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1864testcase TC_attach_echo_timeout() runs on test_CT {
1865 var BSSGP_ConnHdlr vc_conn;
1866 g_use_echo := true;
1867 f_init();
1868 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1869 vc_conn.done;
1870 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001871 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001872}
1873
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001874private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001875 var Gtp1cUnitdata g_ud;
1876 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1877
1878 /* first perform regular attach */
1879 f_TC_attach(id);
1880 /* Activate a pdp context against the GGSN */
1881 f_pdp_ctx_act(apars);
1882 /* Wait to receive first echo request and send initial Restart counter */
1883 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1884 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1885 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1886 }
1887 /* Wait to receive second echo request and send incremented Restart
1888 counter. This will fake a restarted GGSN, and pdp ctx allocated
1889 should be released by SGSN */
1890 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1891 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1892 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1893 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1894 }
1895 var OCT1 cause_network_failure := int2oct(38, 1)
1896 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001897 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001898 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001899 setverdict(pass);
1900 }
1901 [] as_xid(apars);
1902 }
1903 setverdict(pass);
1904}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001905/* ATTACH + trigger Recovery procedure through EchoResp */
1906testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001907 var BSSGP_ConnHdlr vc_conn;
1908 g_use_echo := true
1909 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001910 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 +02001911 vc_conn.done;
1912 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001913 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001914}
1915
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001916private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1917 var Gtp1cUnitdata g_ud;
1918 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1919 var integer seq_nr := 23;
1920 var GtpPeer peer;
1921 /* first perform regular attach */
1922 f_TC_attach(id);
1923
1924 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1925 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1926 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1927 f_pdp_ctx_act(apars, true);
1928
1929 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1930/* received. */
1931 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1932
1933 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1934 would be great to have an active pdp context here before triggering
1935 Recovery, and making sure the the DEACT request is sent by the SGSN.
1936 */
1937
1938 /* Activate a pdp context against the GGSN, send incremented Recovery
1939 IE. This should trigger the recovery path, but still this specific
1940 CTX activation should work. */
1941 apars.exp_rej_cause := omit; /* default value for tests */
1942 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1943 f_pdp_ctx_act(apars, true);
1944
1945 setverdict(pass);
1946}
1947/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1948testcase TC_attach_restart_ctr_create() runs on test_CT {
1949 var BSSGP_ConnHdlr vc_conn;
1950 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001951 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 +02001952 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001953 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001954}
1955
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001956/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1957private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1958 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1959 var integer seq_nr := 23;
1960 var GtpPeer peer;
1961 var integer i;
1962
1963 /* first perform regular attach */
1964 f_TC_attach(id);
1965 /* then activate PDP context */
1966 f_pdp_ctx_act(apars);
1967
Alexander Couzens0e510e62018-07-28 23:06:00 +02001968 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001969 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1970 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1971
1972 for (i := 0; i < 5; i := i+1) {
1973 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001974 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001975 [] as_xid(apars);
1976 }
1977 }
1978
1979 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1980
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001981 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001982 setverdict(pass);
1983}
1984testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1985 var BSSGP_ConnHdlr vc_conn;
1986 f_init();
1987 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001988 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 +02001989 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001990 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001991}
1992
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001993/* ATTACH + PDP CTX ACT dropped + retrans */
1994private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1995 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1996 var Gtp1cUnitdata g_ud_first, g_ud_second;
1997 /* first perform regular attach */
1998 f_TC_attach(id);
1999
2000 /* then activate PDP context on the Gb side */
2001 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2002 apars.apn, apars.pco), 0);
2003
2004 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2005 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2006 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2007 if (g_ud_first != g_ud_second) {
2008 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2009 mtc.stop;
2010 }
2011 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2012 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2013 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2014 apars.sgsn_tei_c, apars.gtp_resp_cause,
2015 apars.ggsn_tei_c, apars.ggsn_tei_u,
2016 apars.nsapi,
2017 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2018 omit, omit));
2019 }
Harald Welte955aa942019-05-03 01:29:29 +02002020 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002021
2022 /* Now the same with Deact */
2023 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2024 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2025 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2026 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2027 if (g_ud_first != g_ud_second) {
2028 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2029 mtc.stop;
2030 }
2031 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2032 BSSGP[0].clear;
2033 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2034 }
2035 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002036 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002037 setverdict(pass);
2038 }
2039 [] as_xid(apars, 0);
2040 }
2041
2042 setverdict(pass);
2043}
2044testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2045 var BSSGP_ConnHdlr vc_conn;
2046 f_init();
2047 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2048 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002049 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002050}
2051
2052/* Test that SGSN GTP response retransmit queue works fine */
2053private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2054 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2055 var integer seq_nr := 23;
2056 var Gtp1cUnitdata g_ud_first, g_ud_second;
2057 var template Gtp1cUnitdata g_delete_req;
2058 /* first perform regular attach + PDP context act */
2059 f_TC_attach(id);
2060 f_pdp_ctx_act(apars);
2061
2062 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2063 BSSGP[0].clear;
2064 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2065 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2066 GTP.send(g_delete_req);
2067 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002068 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002069 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2070 }
2071 [] as_xid(apars, 0);
2072 }
2073 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2074 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2075 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2076 mtc.stop;
2077 }
2078 };
2079
2080 /* Send duplicate DeleteCtxReq */
2081 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2082 GTP.send(g_delete_req);
2083 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2084 if (g_ud_first != g_ud_second) {
2085 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2086 mtc.stop;
2087 }
2088 }
2089
2090 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2091 * is handled differently by SGSN (expect "non-existent" cause) */
2092 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2093 GTP.send(g_delete_req);
2094 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2095 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2096 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2097 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2098 mtc.stop;
2099 }
2100 }
2101
2102 setverdict(pass);
2103}
2104testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2105 var BSSGP_ConnHdlr vc_conn;
2106 f_init();
2107 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2108 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002109 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002110}
2111
Alexander Couzens5e307b42018-05-22 18:12:20 +02002112private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2113 /* MS: perform regular attach */
2114 f_TC_attach(id);
2115
2116 /* HLR: cancel the location request */
2117 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2118 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002119
2120 /* ensure no Detach Request got received */
2121 timer T := 5.0;
2122 T.start;
2123 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002124 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002125 T.stop;
2126 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002127 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002128 }
2129 [] T.timeout {
2130 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002131 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002132 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002133 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002134 repeat;
2135 }
2136 }
2137}
2138
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002139/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2140private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2141 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2142
2143 /* first perform regular attach */
2144 f_TC_attach(id);
2145 /* then activate PDP context */
2146 f_pdp_ctx_act(apars);
2147 /* then transceive a downlink PDU */
2148 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2149
2150 /* Send Error indication as response from upload PDU and expect deact towards MS */
2151 f_pdp_ctx_deact_mt(apars, true);
2152}
2153testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2154 var BSSGP_ConnHdlr vc_conn;
2155 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002156 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 +02002157 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002158 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002159}
2160
Alexander Couzens5e307b42018-05-22 18:12:20 +02002161testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2162 /* MS <-> SGSN: GMM Attach
2163 * HLR -> SGSN: Cancel Location Request
2164 * HLR <- SGSN: Cancel Location Ack
2165 */
2166 var BSSGP_ConnHdlr vc_conn;
2167 f_init();
2168 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002169 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002170 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002171 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002172}
2173
2174
Alexander Couzensc87967a2018-05-22 16:09:54 +02002175private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2176 /* MS: perform regular attach */
2177 f_TC_attach(id);
2178
2179 /* HLR: cancel the location request */
2180 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2181 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2182 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2183
2184 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002185 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002186 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002187
2188 setverdict(pass);
2189}
2190
2191testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2192 /* MS <-> SGSN: GMM Attach
2193 * HLR -> SGSN: Cancel Location Request
2194 * HLR <- SGSN: Cancel Location Ack
2195 * MS <- SGSN: Detach Request
2196 * SGSN-> MS: Detach Complete
2197 */
2198 var BSSGP_ConnHdlr vc_conn;
2199 f_init();
2200 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002201 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002202 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002203 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002204}
2205
2206
Alexander Couzens6c47f292018-05-22 17:09:49 +02002207private function f_hlr_location_cancel_request_unknown_subscriber(
2208 charstring id,
2209 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2210
2211 /* HLR: cancel the location request */
2212 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2213
2214 /* cause 2 = IMSI_UNKNOWN */
2215 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2216
2217 setverdict(pass);
2218}
2219
2220private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002221 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002222}
2223
2224testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2225 /* HLR -> SGSN: Cancel Location Request
2226 * HLR <- SGSN: Cancel Location Error
2227 */
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_unknown_subscriber_withdraw), testcasename(), g_gb, 30);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002233 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002234 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002235}
2236
2237private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002238 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002239}
2240
2241testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2242 /* HLR -> SGSN: Cancel Location Request
2243 * HLR <- SGSN: Cancel Location Error
2244 */
2245
2246 var BSSGP_ConnHdlr vc_conn;
2247 f_init();
2248 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002249 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 +02002250 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002251 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002252}
2253
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002254private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2255 f_TC_attach(id);
2256 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2257}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002258
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002259testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2260 /* MS <-> SGSN: Attach
2261 * MS -> SGSN: Detach Req (Power off)
2262 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2263 */
2264 var BSSGP_ConnHdlr vc_conn;
2265 var integer id := 33;
2266 var charstring imsi := hex2str(f_gen_imsi(id));
2267
2268 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002269 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002270 vc_conn.done;
2271
2272 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002273 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002274}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002275
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002276/* Attempt an attach, but loose the Identification Request (IMEI) */
2277private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2278 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002279 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002280
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002281 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 +02002282
2283 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002284 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002285 /* break */
2286 }
Harald Welte955aa942019-05-03 01:29:29 +02002287 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002288 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002289 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002290 repeat;
2291 }
Harald Welte955aa942019-05-03 01:29:29 +02002292 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002293 /* ignore ID REQ IMEI */
2294 count_req := count_req + 1;
2295 repeat;
2296 }
2297 }
2298 if (count_req != 5) {
2299 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002300 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002301 }
2302 setverdict(pass);
2303}
2304
2305testcase TC_attach_no_imei_response() runs on test_CT {
2306 /* MS -> SGSN: Attach Request IMSI
2307 * MS <- SGSN: Identity Request IMSI (optional)
2308 * MS -> SGSN: Identity Response IMSI (optional)
2309 * MS <- SGSN: Identity Request IMEI
2310 * MS -x SGSN: no response
2311 * MS <- SGSN: re-send: Identity Request IMEI 4x
2312 * MS <- SGSN: Attach Reject
2313 */
2314 var BSSGP_ConnHdlr vc_conn;
2315 f_init();
2316 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002317 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 +02002318 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002319 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002320}
2321
Alexander Couzens53f20562018-06-12 16:24:12 +02002322/* Attempt an attach, but loose the Identification Request (IMSI) */
2323private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2324 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002325 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002326
2327 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2328 g_pars.p_tmsi := 'c0000035'O;
2329
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002330 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 +02002331
2332 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002333 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002334 /* break */
2335 }
Harald Welte955aa942019-05-03 01:29:29 +02002336 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002337 /* ignore ID REQ IMSI */
2338 count_req := count_req + 1;
2339 repeat;
2340 }
Harald Welte955aa942019-05-03 01:29:29 +02002341 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002342 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002343 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002344 repeat;
2345 }
2346 }
2347 if (count_req != 5) {
2348 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002349 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002350 }
2351 setverdict(pass);
2352}
2353
2354testcase TC_attach_no_imsi_response() runs on test_CT {
2355 /* MS -> SGSN: Attach Request TMSI (unknown)
2356 * MS <- SGSN: Identity Request IMEI (optional)
2357 * MS -> SGSN: Identity Response IMEI (optional)
2358 * MS <- SGSN: Identity Request IMSI
2359 * MS -x SGSN: no response
2360 * MS <- SGSN: re-send: Identity Request IMSI 4x
2361 * MS <- SGSN: Attach Reject
2362 */
2363 var BSSGP_ConnHdlr vc_conn;
2364 f_init();
2365 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002366 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 +02002367 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002368 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002369}
2370
Alexander Couzenscf818962018-06-05 18:00:00 +02002371private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2372 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2373}
2374
2375testcase TC_attach_check_subscriber_list() runs on test_CT {
2376 /* MS <-> SGSN: Attach
2377 * VTY -> SGSN: Check if MS is in subscriber cache
2378 */
2379 var BSSGP_ConnHdlr vc_conn;
2380 var integer id := 34;
2381 var charstring imsi := hex2str(f_gen_imsi(id));
2382
2383 f_init();
2384 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002385 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002386 vc_conn.done;
2387
2388 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2389 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002390 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002391}
2392
Alexander Couzensf9858652018-06-07 16:14:53 +02002393private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2394 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002395 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002396
2397 /* unregister the old IMSI */
2398 f_bssgp_client_unregister(g_pars.imsi);
2399 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002400 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002401 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002402
2403 /* there is no auth */
2404 g_pars.net.expect_auth := false;
2405
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002406 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002407 f_gmm_auth();
2408 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002409 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002410 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002411 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002412 }
Harald Welte955aa942019-05-03 01:29:29 +02002413 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2414 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002415 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002416 setverdict(pass);
2417 }
2418 }
2419}
Alexander Couzens03d12242018-08-07 16:13:52 +02002420
2421private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2422
2423 f_TC_attach_closed_foreign(id);
2424 f_TC_attach_closed_imsi_added(id);
2425
2426}
2427
2428
Alexander Couzensf9858652018-06-07 16:14:53 +02002429testcase TC_attach_closed_add_vty() runs on test_CT {
2430 /* VTY-> SGSN: policy close
2431 * MS -> SGSN: Attach Request
2432 * MS <- SGSN: Identity Request IMSI
2433 * MS -> SGSN: Identity Response IMSI
2434 * MS <- SGSN: Attach Reject
2435 * VTY-> SGSN: policy imsi-acl add IMSI
2436 * MS -> SGSN: Attach Request
2437 * MS <- SGSN: Identity Request IMSI
2438 * MS -> SGSN: Identity Response IMSI
2439 * MS <- SGSN: Identity Request IMEI
2440 * MS -> SGSN: Identity Response IMEI
2441 * MS <- SGSN: Attach Accept
2442 */
2443 var BSSGP_ConnHdlr vc_conn;
2444 f_init();
2445 f_sleep(1.0);
2446 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2447 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002448 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2449 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002450 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002451 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002452 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002453 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002454}
2455
Alexander Couzens0085bd72018-06-12 19:08:44 +02002456/* Attempt an attach, but never answer a Attach Complete */
2457private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2458 var integer count_req := 0;
2459
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002460 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 +02002461 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002462 /* Expect SGSN to perform LU with HLR */
2463 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002464
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002465 timer T := 10.0;
2466 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002467 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002468 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469 /* break */
2470 }
Harald Welte955aa942019-05-03 01:29:29 +02002471 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002472 /* ignore */
2473 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002474 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002475 repeat;
2476 }
2477 }
2478 if (count_req != 5) {
2479 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002480 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002481 }
2482 setverdict(pass);
2483}
2484
2485testcase TC_attach_check_complete_resend() runs on test_CT {
2486 /* MS -> SGSN: Attach Request IMSI
2487 * MS <- SGSN: Identity Request *
2488 * MS -> SGSN: Identity Response *
2489 * MS <- SGSN: Attach Complete 5x
2490 */
2491 var BSSGP_ConnHdlr vc_conn;
2492 f_init();
2493 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002494 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 +02002495 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002496 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002497}
2498
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002499friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002500 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002501 var PDU_DTAP_PS_MT mt;
2502 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002503
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002504 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002505 p_tmsi := g_pars.p_tmsi;
2506 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002507 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002508 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 +02002509 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002510 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2511 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2512 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002513 setverdict(pass);
2514 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002515 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2516 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2517 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002518 setverdict(pass);
2519 }
2520
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002521 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002522 setverdict(fail, "Unexpected RAU Reject");
2523 mtc.stop;
2524 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002525 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002526 setverdict(fail, "Unexpected RAU Reject");
2527 mtc.stop;
2528 }
2529
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002530 [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 +02002531 key_sts := ?)) {
2532 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2533 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002534 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002535 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002536 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002537 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2538 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002539 }
2540}
2541
Alexander Couzensbfda9212018-07-31 03:17:33 +02002542private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002543 /* first perform regular attach */
2544 f_TC_attach(id);
2545
2546 /* then send RAU */
2547 f_routing_area_update(g_pars.ra);
2548
2549 /* do another RAU */
2550 f_routing_area_update(g_pars.ra);
2551
2552 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2553}
2554
2555testcase TC_attach_rau_a_a() runs on test_CT {
2556 /* MS <-> SGSN: Successful Attach
2557 * MS -> SGSN: Routing Area Update Request
2558 * MS <- SGSN: Routing Area Update Accept
2559 * MS -> SGSN: Routing Area Update Request
2560 * MS <- SGSN: Routing Area Update Accept
2561 * MS -> SGSN: Detach (PowerOff)
2562 */
2563 var BSSGP_ConnHdlr vc_conn;
2564 f_init();
2565 f_sleep(1.0);
2566 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2567 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002568 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002569}
2570
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002571private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002572 f_TC_attach(id);
2573
2574 log("attach complete sending rau");
2575 f_routing_area_update(g_pars.ra, 0);
2576
2577 log("rau complete unregistering");
2578 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002579 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002580
2581 log("sending second RAU via different RA");
2582 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2583
2584 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2585}
2586
2587testcase TC_attach_rau_a_b() runs on test_CT {
2588 /* MS <-> SGSN: Successful Attach
2589 * MS -> SGSN: Routing Area _a_ Update Request
2590 * MS <- SGSN: Routing Area _a_ Update Accept
2591 * MS -> SGSN: Routing Area _b_ Update Request
2592 * MS <- SGSN: Routing Area _b_ Update Accept
2593 * MS -> SGSN: Detach (PowerOff)
2594 */
2595 var BSSGP_ConnHdlr vc_conn;
2596 f_init();
2597 f_sleep(1.0);
2598 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2599 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002600 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002601}
2602
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002603private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2604 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002605 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002606 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002607 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002608
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002609 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002610
2611 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002612 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002613 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2614 mtc.stop;
2615 }
Harald Welte955aa942019-05-03 01:29:29 +02002616 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002617 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002618 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002619 repeat;
2620 }
Harald Welte955aa942019-05-03 01:29:29 +02002621 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002622 /* send out a second GMM_Attach Request.
2623 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2624 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002625 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002626 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002627 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002628 }
2629 }
2630 f_sleep(1.0);
2631
2632 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2633 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002634 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002635 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002636 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002637 repeat;
2638 }
Harald Welte955aa942019-05-03 01:29:29 +02002639 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002640 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2641 mtc.stop;
2642 }
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_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2648 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002649 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002650 setverdict(pass);
2651 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2652 }
2653 }
2654}
2655
2656testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2657 /* Testing if the SGSN ignore Attach Request with the exact same content */
2658 /* MS -> SGSN: Attach Request IMSI
2659 * MS <- SGSN: Identity Request IMSI (optional)
2660 * MS -> SGSN: Identity Response IMSI (optional)
2661 * MS <- SGSN: Identity Request IMEI
2662 * MS -> SGSN: Attach Request (2nd)
2663 * MS <- SGSN: Identity Response IMEI
2664 * MS <- SGSN: Attach Accept
2665 * MS -> SGSN: Attach Complete
2666 */
2667 var BSSGP_ConnHdlr vc_conn;
2668 f_init();
2669 f_sleep(1.0);
2670 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2671 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2672 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002673 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002674}
2675
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002676private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002677 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2678
2679 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2680
2681 /* send Attach Request */
2682 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2683 * 3G auth vectors */
2684 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2685 /* The thing is, if the solSACapability is 'omit', then the
2686 * revisionLevelIndicatior is at the wrong place! */
2687 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002688 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002689
2690 /* do the auth */
2691 var PDU_L3_MS_SGSN l3_mo;
2692 var PDU_L3_SGSN_MS l3_mt;
2693 var default di := activate(as_mm_identity());
2694
2695 var GSUP_IE auth_tuple;
2696 var template AuthenticationParameterAUTNTLV autn;
2697
2698 g_pars.vec := f_gen_auth_vec_3g();
2699 autn := {
2700 elementIdentifier := '28'O,
2701 lengthIndicator := lengthof(g_pars.vec.autn),
2702 autnValue := g_pars.vec.autn
2703 };
2704 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2705 g_pars.vec.sres,
2706 g_pars.vec.kc,
2707 g_pars.vec.ik,
2708 g_pars.vec.ck,
2709 g_pars.vec.autn,
2710 g_pars.vec.res));
2711 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2712 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2713 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2714
2715 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2716 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002717 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002718
2719 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002720 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002721
2722 /* wait for the GSUP resync request */
2723 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2724 g_pars.imsi,
2725 g_pars.vec.auts,
2726 g_pars.vec.rand));
2727
2728 /* generate new key material */
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
2736 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2737 g_pars.vec.sres,
2738 g_pars.vec.kc,
2739 g_pars.vec.ik,
2740 g_pars.vec.ck,
2741 g_pars.vec.autn,
2742 g_pars.vec.res));
2743 /* send new key material */
2744 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2745
2746 /* wait for the new Auth Request */
2747 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2748 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002749 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002750 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2751 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2752 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2753 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2754 valueField := substr(g_pars.vec.res, 0, 4)
2755 };
2756 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2757 elementIdentifier := '21'O,
2758 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2759 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2760 };
2761 l3_mo := valueof(auth_ciph_resp);
2762 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2763 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2764 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2765 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2766 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002767 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002768 deactivate(di);
2769
2770 /* Expect SGSN to perform LU with HLR */
2771 f_gmm_gsup_lu_isd();
2772
Harald Welte955aa942019-05-03 01:29:29 +02002773 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2774 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002775 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002776 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002777 setverdict(pass);
2778}
2779
2780testcase TC_attach_usim_resync() runs on test_CT {
2781 /* MS -> SGSN: Attach Request
2782 * MS <- SGSN: Identity Request IMSI
2783 * MS -> SGSN: Identity Response IMSI
2784 * MS <- SGSN: Identity Request IMEI
2785 * MS -> SGSN: Identity Response IMEI
2786 * HLR<- SGSN: SAI Request
2787 * HLR-> SGSN: SAI Response
2788 * MS <- SGSN: Auth Request
2789 * MS -> SGSN: Auth Failure (with AUTS)
2790 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2791 * HLR-> SGSN: SAI Response (new key material)
2792 * MS <- SGSN: Auth Request (new key material)
2793 * MS -> SGSN: Auth Response
2794 * MS <- SGSN: Attach Accept
2795 * MS -> SGSN: Attach Complete
2796 */
2797 var BSSGP_ConnHdlr vc_conn;
2798 f_init();
2799 f_sleep(1.0);
2800 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2801 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002802 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002803}
2804
Harald Weltea05b8072019-04-23 22:35:05 +02002805
2806/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2807private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2808 f_gmm_attach(false, false);
2809 f_sleep(1.0);
2810 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2811 /* try to detach to check if SGSN is still alive */
2812 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2813}
2814testcase TC_llc_null() runs on test_CT {
2815 var BSSGP_ConnHdlr vc_conn;
2816 f_init();
2817 f_sleep(1.0);
2818 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2819 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002820 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002821}
2822
Harald Welte645a1512019-04-23 23:18:23 +02002823/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2824private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2825 f_gmm_attach(false, false);
2826 f_sleep(1.0);
2827 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002828 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002829 setverdict(pass);
2830}
2831testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2832 var BSSGP_ConnHdlr vc_conn;
2833 f_init();
2834 f_sleep(1.0);
2835 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2836 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002837 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002838}
2839
2840/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2841private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2842 f_gmm_attach(false, false);
2843 f_sleep(1.0);
2844 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002845 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002846 setverdict(pass);
2847}
2848testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2849 var BSSGP_ConnHdlr vc_conn;
2850 f_init();
2851 f_sleep(1.0);
2852 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2853 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002854 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002855}
2856
Harald Welte2aaac1b2019-05-02 10:02:53 +02002857/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2858private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2859 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2860 var template (value) XID_Information xid;
2861 var template XID_Information xid_rx;
2862
2863 /* first perform regular attach */
2864 f_TC_attach(id);
2865 /* then activate PDP context */
2866 f_pdp_ctx_act(apars);
2867
2868 /* start MO XID */
2869 xid := { ts_XID_L3(''O) };
2870 xid_rx := { tr_XID_L3(''O) };
2871 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2872 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002873 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002874 [] as_xid(apars);
2875 }
2876 setverdict(pass);
2877}
2878testcase TC_xid_empty_l3() runs on test_CT {
2879 var BSSGP_ConnHdlr vc_conn;
2880 f_init();
2881 f_sleep(1.0);
2882 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2883 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002884 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002885}
2886
2887private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2888 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2889 var template (value) XID_Information xid;
2890 var template XID_Information xid_rx;
2891
2892 /* first perform regular attach */
2893 f_TC_attach(id);
2894 /* then activate PDP context */
2895 f_pdp_ctx_act(apars);
2896
2897 /* start MO XID */
2898 xid := { ts_XID_N201U(1234) };
2899 xid_rx := { tr_XID_N201U(1234) };
2900 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2901 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002902 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002903 [] as_xid(apars);
2904 }
2905 setverdict(pass);
2906}
2907testcase TC_xid_n201u() runs on test_CT {
2908 var BSSGP_ConnHdlr vc_conn;
2909 f_init();
2910 f_sleep(1.0);
2911 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2912 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002913 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002914}
2915
Alexander Couzens6bee0872019-05-11 01:48:50 +02002916private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2917 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2918
2919 /* first perform regular attach */
2920 f_TC_attach(id);
2921 /* then activate PDP context */
2922 f_pdp_ctx_act(apars);
2923 /* do a normal detach */
2924 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2925}
2926
2927testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2928 /* MS -> SGSN: Attach Request
2929 * MS <-> SGSN: [..]
2930 * MS -> SGSN: Attach Complete
2931 * MS -> SGSN: PDP Activate Request
2932 * MS <- SGSN: PDP Activate Accept
2933 * MS -> SGSN: GMM Detach Request
2934 * MS <- SGSN: GMM Detach Accept
2935 */
2936 var BSSGP_ConnHdlr vc_conn;
2937 f_init();
2938 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2939 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002940 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002941}
Harald Welte645a1512019-04-23 23:18:23 +02002942
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002943private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2944 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2945 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2946 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2947 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2948 var PDU_L3_SGSN_MS l3_mt;
2949
2950 f_send_l3(attach_req, 0);
2951
2952 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2953
2954 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2955 alt {
2956 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2957 setverdict(pass);
2958 }
2959 [] BSSGP[0].receive { repeat; }
2960 }
2961}
2962
2963/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2964 * See OS#3957 and OS#4245 for more information.
2965 */
2966testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2967 /*
2968 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2969 * MS <-- SGSN: Identity Request (IMEI)
2970 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2971 */
2972 var BSSGP_ConnHdlr vc_conn;
2973 f_init();
2974 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2975 vc_conn.done;
2976 f_cleanup();
2977}
2978
Harald Welte8e5932e2020-06-17 22:12:54 +02002979private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2980var PDU_BSSGP rx;
2981[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2982 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2983 mtc.stop;
2984 }
2985}
2986
2987/* SUSPEND, then DL traffic: should not pass + no paging expected */
2988private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2989 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2990 var default d;
2991
2992 /* first perform regular attach */
2993 f_TC_attach(id);
2994 /* then activate PDP context */
2995 f_pdp_ctx_act(apars);
2996 /* then transceive a downlink PDU */
2997 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2998
2999 /* now suspend GPRS */
3000 f_bssgp_suspend();
3001
3002 d := activate(as_nopaging_ps());
3003
3004 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3005 * nor any related paging requests */
3006 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3007
3008 deactivate(d);
3009}
3010testcase TC_suspend_nopaging() runs on test_CT {
3011 var BSSGP_ConnHdlr vc_conn;
3012 f_init();
3013 f_sleep(1.0);
3014 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3015 vc_conn.done;
3016 f_cleanup();
3017}
3018
3019
3020/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3021private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3022 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3023 var OCT1 susp_ref;
3024 var default d;
3025
3026 /* first perform regular attach */
3027 f_TC_attach(id);
3028 /* then activate PDP context */
3029 f_pdp_ctx_act(apars);
3030 /* then transceive a downlink PDU */
3031 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3032
3033 /* now suspend GPRS */
3034 susp_ref := f_bssgp_suspend();
3035
3036 d := activate(as_nopaging_ps());
3037
3038 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3039 * nor any related paging requests */
3040 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3041
3042 deactivate(d);
3043
3044 /* resume GPRS */
3045 f_bssgp_resume(susp_ref);
3046
3047 /* now data should be flowing again */
3048 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3049}
3050testcase TC_suspend_resume() runs on test_CT {
3051 var BSSGP_ConnHdlr vc_conn;
3052 f_init();
3053 f_sleep(1.0);
3054 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3055 vc_conn.done;
3056 f_cleanup();
3057}
3058
3059/* SUSPEND, then RAU: data expected to flow after implicit resume */
3060private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3061 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3062 var default d;
3063
3064 /* first perform regular attach */
3065 f_TC_attach(id);
3066 /* then activate PDP context */
3067 f_pdp_ctx_act(apars);
3068 /* then transceive a downlink PDU */
3069 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3070
3071 /* now suspend GPRS */
3072 f_bssgp_suspend();
3073
3074 d := activate(as_nopaging_ps());
3075
3076 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3077 * nor any related paging requests */
3078 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3079
3080 deactivate(d);
3081
3082 /* perform RAU (implicit RESUME) */
3083 f_routing_area_update(g_pars.ra);
3084
3085 /* now data should be flowing again */
3086 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3087
3088}
3089testcase TC_suspend_rau() runs on test_CT {
3090 var BSSGP_ConnHdlr vc_conn;
3091 f_init();
3092 f_sleep(1.0);
3093 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3094 vc_conn.done;
3095 f_cleanup();
3096}
3097
3098
3099/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3100private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3101 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3102 var default d;
3103
3104 /* first perform regular attach */
3105 f_TC_attach(id);
3106 /* then activate PDP context */
3107 f_pdp_ctx_act(apars);
3108 /* then transceive a downlink PDU */
3109 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3110
3111 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3112 f_sleep(5.0);
3113
3114 /* now data should be flowing again, but with PS PAGING */
3115 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3116 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3117
3118 /* FIXME: simulate paging response */
3119 /* FIXME: verify PDU actually arrives only after paging response was successful */
3120
3121}
3122testcase TC_paging_ps() runs on test_CT {
3123 var BSSGP_ConnHdlr vc_conn;
3124 f_init();
3125 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3126 f_sleep(1.0);
3127 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3128 vc_conn.done;
3129 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3130 f_cleanup();
3131}
3132
3133
3134
3135
3136
Harald Welte5ac31492018-02-15 20:39:13 +01003137control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003138 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003139 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003140 execute( TC_attach_umts_aka_umts_res() );
3141 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003142 execute( TC_attach_auth_id_timeout() );
3143 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003144 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003145 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003146 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003147 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003148 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003149 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003150 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003151 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003152 execute( TC_attach_closed_add_vty(), 20.0 );
3153 execute( TC_attach_check_subscriber_list(), 20.0 );
3154 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003155 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003156 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3157 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3158 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3159 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003160 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003161 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003162 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003163 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003164 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003165 execute( TC_detach_unknown_nopoweroff() );
3166 execute( TC_detach_unknown_poweroff() );
3167 execute( TC_detach_nopoweroff() );
3168 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003169 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003170 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003171 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003172 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003173 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003174 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003175 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003176 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003177 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003178 execute( TC_attach_restart_ctr_echo() );
3179 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003180 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003181 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3182 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003183 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003184 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003185 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003186
Harald Welte2aaac1b2019-05-02 10:02:53 +02003187 execute( TC_xid_empty_l3() );
3188 execute( TC_xid_n201u() );
3189
Harald Weltea05b8072019-04-23 22:35:05 +02003190 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003191 execute( TC_llc_sabm_dm_llgmm() );
3192 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003193
Harald Welte8e5932e2020-06-17 22:12:54 +02003194 execute( TC_suspend_nopaging() );
3195 execute( TC_suspend_resume() );
3196 execute( TC_suspend_rau() );
3197 execute( TC_paging_ps() );
3198
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003199 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3200 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003201}
Harald Welte96a33b02018-02-04 10:36:22 +01003202
3203
3204
3205}