blob: fe31ffcb3f7c482a5e998e27d8e6576493fabbdc [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
Philipp Maier7df55e02020-12-14 23:46:04 +0100174 /* used by RIM related test */
175 port BSSGP_PT RIM[NUM_GB];
176
Harald Welteeded9ad2018-02-17 20:57:34 +0100177 var GTP_Emulation_CT vc_GTP;
178
Harald Weltebd194722018-02-16 22:11:08 +0100179 port TELNETasp_PT SGSNVTY;
180
Harald Welte96a33b02018-02-04 10:36:22 +0100181 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200182 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100183};
184
Harald Welte26fbb6e2019-04-14 17:32:46 +0200185type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100186 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100187 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200188 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100189}
190
191type record SGSN_ConnHdlrNetworkPars {
192 boolean expect_ptmsi,
193 boolean expect_auth,
194 boolean expect_ciph
195};
196
197type record BSSGP_ConnHdlrPars {
198 /* IMEI of the simulated ME */
199 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200200 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100201 hexstring imsi,
202 /* MSISDN of the simulated MS (probably unused) */
203 hexstring msisdn,
204 /* P-TMSI allocated to the simulated MS */
205 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100206 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100207 /* TLLI of the simulated MS */
208 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100209 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100210 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200211 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200212 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
213 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100214 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100215 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200216 float t_guard,
217 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200218 SCCP_PAR_Address sccp_addr_local optional,
219 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100220};
221
Alexander Couzens89508702018-07-31 04:16:10 +0200222private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200223 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200224 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
225
226 var RoutingAreaIdentificationV ret := {
227 mccDigit1 := mcc_mnc[0],
228 mccDigit2 := mcc_mnc[1],
229 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200230 mncDigit3 := mcc_mnc[3],
231 mncDigit1 := mcc_mnc[4],
232 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200233 lac := int2oct(cell_id.ra_id.lai.lac, 16),
234 rac := int2oct(cell_id.ra_id.rac, 8)
235 }
236 return ret;
237};
238
Alexander Couzens51114d12018-07-31 18:41:56 +0200239private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
240 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
241 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100242 /* connect lower end of BSSGP emulation with NS upper port */
243 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100244
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200245 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200246 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
247 /* resolve the per-BVC component references */
248 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
249 connect(self:PROC, gb.vc_BSSGP:PROC);
250 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
251 disconnect(self:PROC, gb.vc_BSSGP:PROC);
252 }
Philipp Maier7df55e02020-12-14 23:46:04 +0100253 /* connect RIM related port */
254 connect(gb.vc_BSSGP:RIM, self:RIM[offset]);
Harald Welte5ac31492018-02-15 20:39:13 +0100255}
256
257private function f_init_gsup(charstring id) runs on test_CT {
258 id := id & "-GSUP";
259 var GsupOps ops := {
260 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
261 };
262
263 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
264 vc_GSUP := GSUP_Emulation_CT.create(id);
265
266 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
267 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
268 /* we use this hack to get events like ASP_IPA_EVENT_UP */
269 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
270
271 vc_GSUP.start(GSUP_Emulation.main(ops, id));
272 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
273
274 /* wait for incoming connection to GSUP port before proceeding */
275 timer T := 10.0;
276 T.start;
277 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700278 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100279 [] T.timeout {
280 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200281 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100282 }
283 }
284}
285
Harald Welteeded9ad2018-02-17 20:57:34 +0100286private function f_init_gtp(charstring id) runs on test_CT {
287 id := id & "-GTP";
288
289 var GtpEmulationCfg gtp_cfg := {
290 gtpc_bind_ip := mp_ggsn_ip,
291 gtpc_bind_port := GTP1C_PORT,
292 gtpu_bind_ip := mp_ggsn_ip,
293 gtpu_bind_port := GTP1U_PORT,
294 sgsn_role := false
295 };
296
297 vc_GTP := GTP_Emulation_CT.create(id);
298 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
299}
300
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200301friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100302 map(self:SGSNVTY, system:SGSNVTY);
303 f_vty_set_prompts(SGSNVTY);
304 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200305 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100306 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
307}
308
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200309private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
310 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200311 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200312 } else {
313 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
314 }
315}
316
Harald Weltebd194722018-02-16 22:11:08 +0100317
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200318/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
319function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200320 var integer i;
321
Harald Welte96a33b02018-02-04 10:36:22 +0100322 if (g_initialized == true) {
323 return;
324 }
325 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100326 g_gb[0].cfg := {
327 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200328 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200329 bvc := {
330 {
331 bvci := 196,
332 cell_id := {
333 ra_id := {
334 lai := {
335 mcc_mnc := mcc_mnc,
336 lac := 13135
337 },
338 rac := 0
339 },
340 cell_id := 20960
341 },
Harald Welte4d112c92020-11-12 19:48:31 +0100342 depth := BSSGP_DECODE_DEPTH_L3,
343 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200344 }
345 }
Harald Welte5ac31492018-02-15 20:39:13 +0100346 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200347 g_gb[1].cfg := {
348 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200349 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200350 bvc := {
351 {
352 bvci := 210,
353 cell_id := {
354 ra_id := {
355 lai := {
356 mcc_mnc := mcc_mnc,
357 lac := 13200
358 },
359 rac := 0
360 },
361 cell_id := 20961
362 },
Harald Welte4d112c92020-11-12 19:48:31 +0100363 depth := BSSGP_DECODE_DEPTH_L3,
364 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200365 }
366 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200367 };
368 g_gb[2].cfg := {
369 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200370 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200371 bvc := {
372 {
373 bvci := 220,
374 cell_id := {
375 ra_id := {
376 lai := {
377 mcc_mnc := mcc_mnc,
378 lac := 13300
379 },
380 rac := 0
381 },
382 cell_id := 20962
383 },
Harald Welte4d112c92020-11-12 19:48:31 +0100384 depth := BSSGP_DECODE_DEPTH_L3,
385 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200386 }
387 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200388 };
Harald Welte96a33b02018-02-04 10:36:22 +0100389
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200390 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200391 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
392 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
393 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200394
Alexander Couzens1552e792019-07-23 20:38:39 +0200395 if (g_ranap_enable) {
396 for (i := 0; i < NUM_RNC; i := i+1) {
397 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
398 f_ran_adapter_start(g_ranap[i]);
399 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200400 }
Harald Welte5ac31492018-02-15 20:39:13 +0100401 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100402 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200403 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100404}
Harald Welte96a33b02018-02-04 10:36:22 +0100405
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200406function f_cleanup() runs on test_CT {
407 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200408 if (g_ranap_enable) {
409 for (i := 0; i < NUM_RNC; i := i+1) {
410 f_ran_adapter_cleanup(g_ranap[i]);
411 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200412 }
413 self.stop;
414}
415
Harald Welte26fbb6e2019-04-14 17:32:46 +0200416private function RncUnitdataCallback(RANAP_PDU ranap)
417runs on RAN_Emulation_CT return template RANAP_PDU {
418 var template RANAP_PDU resp := omit;
419
420 log ("RANAP_RncUnitDataCallback");
421 /* answer all RESET with RESET ACK */
422 if (match(ranap, tr_RANAP_Reset)) {
423 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
424 var CN_DomainIndicator dom;
425 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
426 resp := ts_RANAP_ResetAck(dom);
427 }
428 return resp;
429}
430
431const RanOps RNC_RanOps := {
432 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
433 ranap_unitdata_cb := refers(RncUnitdataCallback),
434 ps_domain := true,
435 decode_dtap := true,
436 role_ms := true,
437 protocol := RAN_PROTOCOL_RANAP,
438 transport := RANAP_TRANSPORT_IuCS,
439 use_osmux := false,
440 sccp_addr_local := omit,
441 sccp_addr_peer := omit
442};
443
Harald Welte5ac31492018-02-15 20:39:13 +0100444type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
445
446/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200447function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100448 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100449runs on test_CT return BSSGP_ConnHdlr {
450 var BSSGP_ConnHdlr vc_conn;
451 var SGSN_ConnHdlrNetworkPars net_pars := {
452 expect_ptmsi := true,
453 expect_auth := true,
454 expect_ciph := false
455 };
456 var BSSGP_ConnHdlrPars pars := {
457 imei := f_gen_imei(imsi_suffix),
458 imsi := f_gen_imsi(imsi_suffix),
459 msisdn := f_gen_msisdn(imsi_suffix),
460 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100461 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100462 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100463 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100464 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200465 bssgp_cell_id := {
466 gb[0].cfg.bvc[0].cell_id,
467 gb[1].cfg.bvc[0].cell_id,
468 gb[2].cfg.bvc[0].cell_id
469 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200470 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100471 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100472 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200473 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200474 sccp_addr_local := omit,
475 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100476 };
477
Alexander Couzens1552e792019-07-23 20:38:39 +0200478 if (g_ranap_enable) {
479 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
480 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
481 }
482
Harald Welte5ac31492018-02-15 20:39:13 +0100483 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200484
485 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
486 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
487 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100488 connect(vc_conn:BSSGP_GLOBAL[0], gb[0].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200489
490 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
491 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
492 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100493 connect(vc_conn:BSSGP_GLOBAL[1], gb[1].vc_BSSGP:GLOBAL);
Harald Welte5339b2e2020-10-04 22:52:56 +0200494
495 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
496 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
497 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte9b461a92020-12-10 23:41:14 +0100498 connect(vc_conn:BSSGP_GLOBAL[2], gb[2].vc_BSSGP:GLOBAL);
Harald Welte5ac31492018-02-15 20:39:13 +0100499
Harald Welte26fbb6e2019-04-14 17:32:46 +0200500 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200501 if (g_ranap_enable) {
502 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
503 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
504 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200505
Harald Welte5ac31492018-02-15 20:39:13 +0100506 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
507 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
508
Harald Welteeded9ad2018-02-17 20:57:34 +0100509 connect(vc_conn:GTP, vc_GTP:CLIENT);
510 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
511
Harald Welte5ac31492018-02-15 20:39:13 +0100512 vc_conn.start(f_handler_init(fn, id, pars));
513 return vc_conn;
514}
515
Harald Welte62e29582018-02-16 21:17:11 +0100516private altstep as_Tguard() runs on BSSGP_ConnHdlr {
517 [] g_Tguard.timeout {
518 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200519 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100520 }
521}
522
Harald Welte5ac31492018-02-15 20:39:13 +0100523/* first function called in every ConnHdlr */
524private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
525runs on BSSGP_ConnHdlr {
526 /* do some common stuff like setting up g_pars */
527 g_pars := pars;
528
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200529 llc := f_llc_create(false);
530
Harald Welte5ac31492018-02-15 20:39:13 +0100531 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200532 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100533 /* tell GSUP dispatcher to send this IMSI to us */
534 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100535 /* tell GTP dispatcher to send this IMSI to us */
536 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100537
Harald Welte62e29582018-02-16 21:17:11 +0100538 g_Tguard.start(pars.t_guard);
539 activate(as_Tguard());
540
Harald Welte5ac31492018-02-15 20:39:13 +0100541 /* call the user-supplied test case function */
542 fn.apply(id);
543 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100544}
545
546/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100547 * Detach without Attach
548 * SM procedures without attach / RAU
549 * ATTACH / RAU
550 ** with / without authentication
551 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100552 * re-transmissions of LLC frames
553 * PDP Context activation
554 ** with different GGSN config in SGSN VTY
555 ** with different PDP context type (v4/v6/v46)
556 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100557 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100558 */
559
560testcase TC_wait_ns_up() runs on test_CT {
561 f_init();
562 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200563 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100564}
565
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200566friend function is_gb(integer ran_index) return boolean {
567 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200568}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200569friend function is_iu(integer ran_index) return boolean {
570 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200571}
572
Alexander Couzens0507ec32019-09-15 22:41:22 +0200573function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200574 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200575 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 +0200576}
577
Alexander Couzens0507ec32019-09-15 22:41:22 +0200578private 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 +0200579 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
580 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
581 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200582 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200583}
584
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200585/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
586function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
587 log("Sending InitialUE: ", l3_mo);
588 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
589 var RANAP_PDU ranap;
590 var LAI lai := {
591 pLMNidentity := '62F224'O,
592 lAC := '1234'O,
593 iE_Extensions := omit
594 };
595 var SAI sai := {
596 pLMNidentity := lai.pLMNidentity,
597 lAC := lai.lAC,
598 sAC := '0000'O, /* FIXME */
599 iE_Extensions := omit
600 };
601 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
602 var GlobalRNC_ID grnc_id := {
603 pLMNidentity := lai.pLMNidentity,
604 rNC_ID := 2342 /* FIXME */
605 };
606
607 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
608 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
609 alt {
610 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
611 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
612 setverdict(fail, "DISC.ind from SCCP");
613 mtc.stop;
614 }
615 }
616}
617
618/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200619function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
620 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200621 if (g_pars.rnc_send_initial_ue) {
622 g_pars.rnc_send_initial_ue := false;
623 f_send_l3_initial_ue(l3_mo);
624 } else {
625 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
626 }
627 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200628 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200629 }
630}
631
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200632altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700633 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200634 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100635 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);
Harald Welte5ac31492018-02-15 20:39:13 +0100637 repeat;
638 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200639 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200640 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
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_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100645 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);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200647 repeat;
648 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200649 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200650 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200651 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100652 repeat;
653 }
654}
Harald Welte96a33b02018-02-04 10:36:22 +0100655
Harald Welteca362462019-05-02 20:11:21 +0200656/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200657function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200658runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200659 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200660 var PDU_L3_SGSN_MS l3_mt;
661 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
663 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200664 l3_mt := mt.dtap;
665 }
Harald Welteca362462019-05-02 20:11:21 +0200666 }
667 return l3_mt;
668}
669
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200670/* perform GMM authentication (if expected).
671 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
672 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200673function 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 +0100674 var PDU_L3_MS_SGSN l3_mo;
675 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200676 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100677 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200678 var GSUP_IE auth_tuple;
679 var template AuthenticationParameterAUTNTLV autn;
680
681 if (umts_aka_challenge) {
682 g_pars.vec := f_gen_auth_vec_3g();
683 autn := {
684 elementIdentifier := '28'O,
685 lengthIndicator := lengthof(g_pars.vec.autn),
686 autnValue := g_pars.vec.autn
687 };
688
689 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
690 g_pars.vec.sres,
691 g_pars.vec.kc,
692 g_pars.vec.ik,
693 g_pars.vec.ck,
694 g_pars.vec.autn,
695 g_pars.vec.res));
696 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
697 } else {
698 g_pars.vec := f_gen_auth_vec_2g();
699 autn := omit;
700 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
701 g_pars.vec.sres,
702 g_pars.vec.kc));
703 log("GSUP sends only 2G auth tuple", auth_tuple);
704 }
Harald Welteca362462019-05-02 20:11:21 +0200705
Harald Welte5ac31492018-02-15 20:39:13 +0100706 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
707 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200708
709 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
710 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200711 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100712 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200713 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
714
715 if (umts_aka_challenge and not force_gsm_sres) {
716 /* set UMTS response instead */
717 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
718 valueField := substr(g_pars.vec.res, 0, 4)
719 };
720 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
721 elementIdentifier := '21'O,
722 lengthIndicator := lengthof(g_pars.vec.res) - 4,
723 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
724 };
725 }
726
727 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100728 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
729 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
730 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
731 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
732 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200733 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200734
735 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200736 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200737 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
738 key_sts := ?)) {
739 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
740 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200741 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200742 }
743 }
Harald Welte76dee092018-02-16 22:12:59 +0100744 } else {
745 /* wait for identity procedure */
746 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100747 }
Harald Welte76dee092018-02-16 22:12:59 +0100748
Harald Welte5ac31492018-02-15 20:39:13 +0100749 deactivate(di);
750}
751
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200752function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100753 g_pars.p_tmsi := p_tmsi;
754 /* update TLLI */
755 g_pars.tlli_old := g_pars.tlli;
756 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100757 if (is_gb(ran_index)) {
758 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
759 }
Harald Weltef70997d2018-02-17 10:11:19 +0100760}
761
Harald Welte04683d02018-02-16 22:43:45 +0100762function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
763 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100764 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200765 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100766 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200767 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200768 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100769 }
Harald Welte04683d02018-02-16 22:43:45 +0100770 g_pars.ra := aa.routingAreaIdentification;
771 if (ispresent(aa.allocatedPTMSI)) {
772 if (not g_pars.net.expect_ptmsi) {
773 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200774 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100775 }
Harald Weltef70997d2018-02-17 10:11:19 +0100776 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100777 }
778 if (ispresent(aa.msIdentity)) {
779 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200780 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100781 }
782 /* P-TMSI.sig */
783 if (ispresent(aa.ptmsiSignature)) {
784 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
785 }
786 /* updateTimer */
787 // aa.readyTimer
788 /* T3302, T3319, T3323, T3312_ext, T3324 */
789}
790
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200791function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100792 /* mandatory IE */
793 g_pars.ra := ra.routingAreaId;
794 if (ispresent(ra.allocatedPTMSI)) {
795 if (not g_pars.net.expect_ptmsi) {
796 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200797 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100798 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200799 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100800 }
801 if (ispresent(ra.msIdentity)) {
802 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200803 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100804 }
805 /* P-TMSI.sig */
806 if (ispresent(ra.ptmsiSignature)) {
807 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
808 }
809 /* updateTimer */
810 // aa.readyTimer
811 /* T3302, T3319, T3323, T3312_ext, T3324 */
812}
813
814
Harald Welte5a4fa042018-02-16 20:59:21 +0100815function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
816 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
817}
818
Harald Welte23178c52018-02-17 09:36:33 +0100819/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700820private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100821 if (ispresent(g_pars.p_tmsi)) {
822 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
823 } else {
824 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
825 }
826}
827
Harald Welte311ec272018-02-17 09:40:03 +0100828private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100829 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100830 /* Expect MSC to perform LU with HLR */
831 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100832 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
833 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
834 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100835 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
836 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
837}
838
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200839friend 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 +0100840 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200841 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 +0200842 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100843
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200844 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
845 * 3G auth vectors */
846 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
847 /* The thing is, if the solSACapability is 'omit', then the
848 * revisionLevelIndicatior is at the wrong place! */
849 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
850
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200851 f_send_l3(attach_req, ran_index);
852 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200853 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100854 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100855
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200856 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200857 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
858
Harald Welte04683d02018-02-16 22:43:45 +0100859 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200860 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200861
862 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200863 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200864 as_iu_release_compl_disc();
865 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200866
867 /* Race condition
868 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
869 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
870 * arrived before it. This results in a test case failure.
871 * Delay execution by 50 ms
872 */
873 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200874}
875
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200876friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
877 timer T := 5.0;
878 var PDU_BSSGP rx_pdu;
Harald Welte9b461a92020-12-10 23:41:14 +0100879 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 +0200880 T.start;
881 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100882 [] 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 +0200883 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
884 }
Harald Welte9b461a92020-12-10 23:41:14 +0100885 [] 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 +0200886 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
887 mtc.stop;
888 }
889 [] T.timeout {
890 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
891 mtc.stop;
892 }
893 }
894 return '00'O;
895}
896
897friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
898 timer T := 5.0;
Harald Welte9b461a92020-12-10 23:41:14 +0100899 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 +0200900 T.start;
901 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100902 [] BSSGP_GLOBAL[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
903 [] 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 +0200904?)) {
905 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
906 mtc.stop;
907 }
908 [] T.timeout {
909 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
910 mtc.stop;
911 }
912 }
913}
914
915
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200916private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
917 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100918 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100919}
920
921testcase TC_attach() runs on test_CT {
922 var BSSGP_ConnHdlr vc_conn;
923 f_init();
924 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200925 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100926 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200927 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100928}
929
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100930testcase TC_attach_mnc3() runs on test_CT {
931 var BSSGP_ConnHdlr vc_conn;
932 f_init('023042'H);
933 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200934 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100935 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200936 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100937}
938
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200939private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
940 f_gmm_attach(true, false);
941 setverdict(pass);
942}
943testcase TC_attach_umts_aka_umts_res() runs on test_CT {
944 var BSSGP_ConnHdlr vc_conn;
945 f_init();
946 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200947 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200948 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200949 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200950}
951
952private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
953 f_gmm_attach(true, true);
954 setverdict(pass);
955}
956testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
957 var BSSGP_ConnHdlr vc_conn;
958 f_init();
959 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200960 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200961 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200962 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200963}
964
Harald Welte5b7c8122018-02-16 21:48:17 +0100965/* MS never responds to ID REQ, expect ATTACH REJECT */
966private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100967 var RoutingAreaIdentificationV old_ra := f_random_RAI();
968
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200969 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100970 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200971 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100972 /* don't send ID Response */
973 repeat;
974 }
Harald Welte955aa942019-05-03 01:29:29 +0200975 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100976 setverdict(pass);
977 }
Harald Welte955aa942019-05-03 01:29:29 +0200978 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100979 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200980 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100981 }
982 }
983}
984testcase TC_attach_auth_id_timeout() runs on test_CT {
985 var BSSGP_ConnHdlr vc_conn;
986 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200987 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 +0100988 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200989 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100990}
991
992/* HLR never responds to SAI REQ, expect ATTACH REJECT */
993private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100994 var RoutingAreaIdentificationV old_ra := f_random_RAI();
995
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200996 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100997 alt {
998 [] as_mm_identity();
999 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
1000 }
1001 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +02001002 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +01001003 setverdict(pass);
1004}
1005testcase TC_attach_auth_sai_timeout() runs on test_CT {
1006 var BSSGP_ConnHdlr vc_conn;
1007 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001008 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001009 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001010 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001011}
1012
Harald Weltefe253882018-02-17 09:25:00 +01001013/* HLR rejects SAI, expect ATTACH REJECT */
1014private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001015 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1016
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001017 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001018 alt {
1019 [] as_mm_identity();
1020 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1021 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1022 }
1023 }
Harald Welte955aa942019-05-03 01:29:29 +02001024 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001025 setverdict(pass);
1026}
1027testcase TC_attach_auth_sai_reject() runs on test_CT {
1028 var BSSGP_ConnHdlr vc_conn;
1029 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001030 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001031 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001032 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001033}
1034
Harald Welte5b7c8122018-02-16 21:48:17 +01001035/* HLR never responds to UL REQ, expect ATTACH REJECT */
1036private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001037 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001038 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1039
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001040 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001041 f_gmm_auth();
1042 /* Expect MSC to perform LU with HLR */
1043 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1044 /* Never follow-up with ISD_REQ or UL_RES */
1045 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001046 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001047 setverdict(pass);
1048 }
Harald Welte955aa942019-05-03 01:29:29 +02001049 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1050 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001051 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001052 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001053 }
1054 }
1055}
1056testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1057 var BSSGP_ConnHdlr vc_conn;
1058 f_init();
1059 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001060 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001061 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001062 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001063}
1064
Harald Welteb7c14e92018-02-17 09:29:16 +01001065/* HLR rejects UL REQ, expect ATTACH REJECT */
1066private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001067 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001068 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1069
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001070 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001071 f_gmm_auth();
1072 /* Expect MSC to perform LU with HLR */
1073 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1074 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1075 }
1076 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001077 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001078 setverdict(pass);
1079 }
Harald Welte955aa942019-05-03 01:29:29 +02001080 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1081 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001082 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001083 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001084 }
1085 }
1086}
1087testcase TC_attach_gsup_lu_reject() runs on test_CT {
1088 var BSSGP_ConnHdlr vc_conn;
1089 f_init();
1090 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001091 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001092 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001093 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001094}
1095
1096
Harald Welte3823e2e2018-02-16 21:53:48 +01001097/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1098private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001099 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001100 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1101
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001102 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001103 f_gmm_auth();
1104 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001105 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001106
Harald Welte955aa942019-05-03 01:29:29 +02001107 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1108 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001109 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001110 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001111 setverdict(pass);
1112}
Harald Welte3823e2e2018-02-16 21:53:48 +01001113testcase TC_attach_combined() runs on test_CT {
1114 var BSSGP_ConnHdlr vc_conn;
1115 f_init();
1116 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001117 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001118 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001119 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001120}
1121
Harald Welte76dee092018-02-16 22:12:59 +01001122/* Attempt of GPRS ATTACH in 'accept all' mode */
1123private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001124 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001125 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1126
1127 g_pars.net.expect_auth := false;
1128
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001129 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001130 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001131 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1132 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001133 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001134 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001135 setverdict(pass);
1136}
1137testcase TC_attach_accept_all() runs on test_CT {
1138 var BSSGP_ConnHdlr vc_conn;
1139 f_init();
1140 f_sleep(1.0);
1141 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001142 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001143 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001144 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001145}
Harald Welte5b7c8122018-02-16 21:48:17 +01001146
Harald Welteb2124b22018-02-16 22:26:56 +01001147/* Attempt of GPRS ATTACH in 'accept all' mode */
1148private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001149 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1150
1151 /* Simulate a foreign IMSI */
1152 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001153 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001154
1155 g_pars.net.expect_auth := false;
1156
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001157 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001158 alt {
1159 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001160 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001161 setverdict(pass);
1162 }
Harald Welte955aa942019-05-03 01:29:29 +02001163 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001164 setverdict(pass);
1165 }
Harald Welte955aa942019-05-03 01:29:29 +02001166 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001167 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001168 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001169 }
Harald Welteb2124b22018-02-16 22:26:56 +01001170 }
1171}
1172testcase TC_attach_closed() runs on test_CT {
1173 var BSSGP_ConnHdlr vc_conn;
1174 f_init();
1175 f_sleep(1.0);
1176 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1177 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001178 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001179 vc_conn.done;
1180 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001181 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001182 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001183 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001184}
1185
Harald Welte04683d02018-02-16 22:43:45 +01001186/* Routing Area Update from Unknown TLLI -> REJECT */
1187private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001188 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1189
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001190 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 +01001191 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001192 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001193 setverdict(pass);
1194 }
1195 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001196 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001197 }
1198}
1199testcase TC_rau_unknown() runs on test_CT {
1200 var BSSGP_ConnHdlr vc_conn;
1201 f_init();
1202 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001203 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001204 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001205 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001206}
1207
Harald Welte91636de2018-02-17 10:16:14 +01001208private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001209 /* first perform regular attach */
1210 f_TC_attach(id);
1211
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001212 f_routing_area_update(g_pars.ra);
1213
Harald Welte91636de2018-02-17 10:16:14 +01001214}
1215testcase TC_attach_rau() runs on test_CT {
1216 var BSSGP_ConnHdlr vc_conn;
1217 f_init();
1218 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001219 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001220 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001221 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001222}
Harald Welte04683d02018-02-16 22:43:45 +01001223
Harald Welte6abb9fe2018-02-17 15:24:48 +01001224/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001225function 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 +02001226 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001227 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001228 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001229 if (expect_purge) {
1230 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1231 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1232 }
1233 T.start;
1234 alt {
1235 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1236 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001237 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001238 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001239 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001240 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001241 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001242 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001243 /* TODO: check if any PDP contexts are deactivated on network side? */
1244 }
1245 [power_off] T.timeout {
1246 setverdict(pass);
1247 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001248 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001249 g_pars.ra := omit;
1250 setverdict(pass);
1251 /* TODO: check if any PDP contexts are deactivated on network side? */
1252 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001253 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001254 if (power_off) {
1255 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1256 } else {
1257 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1258 }
1259 mtc.stop;
1260 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001261 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001262 }
1263}
1264
1265/* IMSI DETACH (non-power-off) for unknown TLLI */
1266private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1267 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1268}
1269testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1270 var BSSGP_ConnHdlr vc_conn;
1271 f_init();
1272 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001273 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001274 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001275 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001276}
1277
1278/* IMSI DETACH (power-off) for unknown TLLI */
1279private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1280 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1281}
1282testcase TC_detach_unknown_poweroff() runs on test_CT {
1283 var BSSGP_ConnHdlr vc_conn;
1284 f_init();
1285 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001286 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001287 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001288 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001289}
1290
1291/* IMSI DETACH (non-power-off) for known TLLI */
1292private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1293 /* first perform regular attach */
1294 f_TC_attach(id);
1295
1296 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1297}
1298testcase TC_detach_nopoweroff() runs on test_CT {
1299 var BSSGP_ConnHdlr vc_conn;
1300 f_init();
1301 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001302 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001303 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001304 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001305}
1306
1307/* IMSI DETACH (power-off) for known TLLI */
1308private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1309 /* first perform regular attach */
1310 f_TC_attach(id);
1311
1312 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1313}
1314testcase TC_detach_poweroff() runs on test_CT {
1315 var BSSGP_ConnHdlr vc_conn;
1316 f_init();
1317 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001318 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001319 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001320 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001321}
1322
Harald Welteeded9ad2018-02-17 20:57:34 +01001323type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001324 BIT3 tid, /* L3 Transaction ID */
1325 BIT4 nsapi, /* SNDCP NSAPI */
1326 BIT4 sapi, /* LLC SAPI */
1327 QoSV qos, /* QoS parameters */
1328 PDPAddressV addr, /* IP address */
1329 octetstring apn optional, /* APN name */
1330 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1331 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001332 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001333 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001334
Harald Welte822f9102018-02-18 20:39:06 +01001335 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1336 OCT4 ggsn_tei_u, /* GGSN TEI User */
1337 octetstring ggsn_ip_c, /* GGSN IP Control */
1338 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001339 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001340
Harald Welte822f9102018-02-18 20:39:06 +01001341 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1342 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1343 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1344 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001345};
1346
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001347
1348private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1349 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1350 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1351 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1352 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1353 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1354 f_gtp_register_teid(apars.ggsn_tei_c);
1355 f_gtp_register_teid(apars.ggsn_tei_u);
1356}
1357
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001358function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001359runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001360 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1361 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001362 var template Recovery_gtpc recovery := omit;
1363
1364 if (send_recovery) {
1365 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1366 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001367
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001368 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 +02001369 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001370 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1371 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1372 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1373 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1374 apars.sgsn_tei_c, apars.gtp_resp_cause,
1375 apars.ggsn_tei_c, apars.ggsn_tei_u,
1376 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001377 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1378 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001379 }
1380 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001381 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001382 setverdict(pass);
1383 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001384 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001385 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001386 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001387 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001388 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001389 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001390 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001391 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001392 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001393 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1394 mtc.stop;
1395 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001396 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001397 setverdict(pass);
1398 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001399 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001400 }
1401}
1402
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001403function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001404runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001405 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1406 var Gtp1cUnitdata g_ud;
1407
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001408 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001409 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1410 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001411 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001412 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1413 }
1414 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001415 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001416 setverdict(pass);
1417 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001418 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001419 }
1420}
1421
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001422function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001423runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001424 var Gtp1cUnitdata g_ud;
1425 var integer seq_nr := 23;
1426 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1427
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001428 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001429 if (error_ind) {
1430 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1431 } else {
1432 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1433 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001434
1435 timer T := 5.0;
1436 T.start;
1437
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001438 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001439 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1440 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001441 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001442 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1443 repeat;
1444 }
1445 [] T.timeout {
1446 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1447 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001448 }
1449}
1450
Harald Welte6f203162018-02-18 22:04:55 +01001451
Harald Welteeded9ad2018-02-17 20:57:34 +01001452/* Table 10.5.156/3GPP TS 24.008 */
1453template (value) QoSV t_QosDefault := {
1454 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1455 delayClass := '100'B, /* best effort */
1456 spare1 := '00'B,
1457 precedenceClass := '010'B, /* normal */
1458 spare2 := '0'B,
1459 peakThroughput := '0000'B, /* subscribed */
1460 meanThroughput := '00000'B, /* subscribed */
1461 spare3 := '000'B,
1462 deliverErroneusSDU := omit,
1463 deliveryOrder := omit,
1464 trafficClass := omit,
1465 maxSDUSize := omit,
1466 maxBitrateUplink := omit,
1467 maxBitrateDownlink := omit,
1468 sduErrorRatio := omit,
1469 residualBER := omit,
1470 trafficHandlingPriority := omit,
1471 transferDelay := omit,
1472 guaranteedBitRateUplink := omit,
1473 guaranteedBitRateDownlink := omit,
1474 sourceStatisticsDescriptor := omit,
1475 signallingIndication := omit,
1476 spare4 := omit,
1477 maxBitrateDownlinkExt := omit,
1478 guaranteedBitRateDownlinkExt := omit,
1479 maxBitrateUplinkExt := omit,
1480 guaranteedBitRateUplinkExt := omit,
1481 maxBitrateDownlinkExt2 := omit,
1482 guaranteedBitRateDownlinkExt2 := omit,
1483 maxBitrateUplinkExt2 := omit,
1484 guaranteedBitRateUplinkExt2 := omit
1485}
1486
1487/* 10.5.6.4 / 3GPP TS 24.008 */
1488template (value) PDPAddressV t_AddrIPv4dyn := {
1489 pdpTypeOrg := '0001'B, /* IETF */
1490 spare := '0000'B,
1491 pdpTypeNum := '21'O, /* IPv4 */
1492 addressInfo := omit
1493}
1494template (value) PDPAddressV t_AddrIPv6dyn := {
1495 pdpTypeOrg := '0001'B, /* IETF */
1496 spare := '0000'B,
1497 pdpTypeNum := '53'O, /* IPv6 */
1498 addressInfo := omit
1499}
1500
Harald Welte37692d82018-02-18 15:21:34 +01001501template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001502 tid := '000'B,
1503 nsapi := '0101'B, /* < 5 are reserved */
1504 sapi := '0011'B, /* 3/5/9/11 */
1505 qos := t_QosDefault,
1506 addr := t_AddrIPv4dyn,
1507 apn := omit,
1508 pco := omit,
1509 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001510 gtp_resp_cause := int2oct(128, 1),
1511 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001512
1513 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001514 ggsn_tei_c := f_rnd_octstring(4),
1515 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001516 ggsn_ip_c := f_inet_addr(ggsn_ip),
1517 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001518 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001519
Harald Welteeded9ad2018-02-17 20:57:34 +01001520 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001521 sgsn_tei_u := omit,
1522 sgsn_ip_c := omit,
1523 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001524}
1525
Harald Welte37692d82018-02-18 15:21:34 +01001526template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1527 connId := 1,
1528 remName := f_inet_ntoa(ip),
1529 remPort := GTP1U_PORT
1530}
1531
1532template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1533 connId := 1,
1534 remName := f_inet_ntoa(ip),
1535 remPort := GTP1C_PORT
1536}
1537
1538private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1539 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1540 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1541}
1542
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001543private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1544 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001545 repeat;
1546 }
1547}
1548
1549template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1550 pDU_SN_UNITDATA := {
1551 nsapi := nsapi,
1552 moreBit := ?,
1553 snPduType := '1'B,
1554 firstSegmentIndicator := ?,
1555 spareBit := ?,
1556 pcomp := ?,
1557 dcomp := ?,
1558 npduNumber := ?,
1559 segmentNumber := ?,
1560 npduNumberContinued := ?,
1561 dataSegmentSnUnitdataPdu := payload
1562 }
1563}
1564
1565/* simple case: single segment, no compression */
1566template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1567 pDU_SN_UNITDATA := {
1568 nsapi := nsapi,
1569 moreBit := '0'B,
1570 snPduType := '1'B,
1571 firstSegmentIndicator := '1'B,
1572 spareBit := '0'B,
1573 pcomp := '0000'B,
1574 dcomp := '0000'B,
1575 npduNumber := '0000'B,
1576 segmentNumber := '0000'B,
1577 npduNumberContinued := '00'O,
1578 dataSegmentSnUnitdataPdu := payload
1579 }
1580}
1581
1582/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001583private 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 +02001584runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001585 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001586 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1587 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001588 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001589 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1590 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001591 [] as_xid(apars, ran_index);
1592 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001593 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1594 [expect_fwd] T.timeout {
1595 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1596 mtc.stop;
1597 }
1598 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1599 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1600 mtc.stop;
1601 }
1602 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001603 }
1604}
1605
Harald Welte64d6b512020-06-17 16:42:00 +02001606/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001607private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001608runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001609 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1610 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1611 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001612 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001613 /* Expect PDU via GTP from SGSN on simulated GGSN */
1614 alt {
1615 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1616 }
1617}
1618
Harald Welteeded9ad2018-02-17 20:57:34 +01001619private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001620 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001621
1622 /* first perform regular attach */
1623 f_TC_attach(id);
1624
1625 f_pdp_ctx_act(apars);
1626}
1627testcase TC_attach_pdp_act() runs on test_CT {
1628 var BSSGP_ConnHdlr vc_conn;
1629 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001630 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001631 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001632 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001633}
Harald Welteb2124b22018-02-16 22:26:56 +01001634
Harald Welte835b15f2018-02-18 14:39:11 +01001635/* PDP Context activation for not-attached subscriber; expect fail */
1636private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001637 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001638 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 +01001639 apars.apn, apars.pco));
1640 alt {
1641 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001642 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001643 setverdict(pass);
1644 }
1645 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1646 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001647 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001648 }
Harald Welte955aa942019-05-03 01:29:29 +02001649 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001650 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001651 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001652 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001653 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001654 }
1655}
1656testcase TC_pdp_act_unattached() runs on test_CT {
1657 var BSSGP_ConnHdlr vc_conn;
1658 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001659 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001660 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001661 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001662}
1663
Harald Welte37692d82018-02-18 15:21:34 +01001664/* ATTACH + PDP CTX ACT + user plane traffic */
1665private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1666 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1667
1668 /* first perform regular attach */
1669 f_TC_attach(id);
1670 /* then activate PDP context */
1671 f_pdp_ctx_act(apars);
1672 /* then transceive a downlink PDU */
1673 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1674 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1675}
1676testcase TC_attach_pdp_act_user() runs on test_CT {
1677 var BSSGP_ConnHdlr vc_conn;
1678 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001679 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001680 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001681 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001682}
1683
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001684/* ATTACH + PDP CTX ACT; reject from GGSN */
1685private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1686 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1687
1688 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1689 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1690
1691 /* first perform regular attach */
1692 f_TC_attach(id);
1693 /* then activate PDP context */
1694 f_pdp_ctx_act(apars);
1695}
1696testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1697 var BSSGP_ConnHdlr vc_conn;
1698 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001699 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001700 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001701 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001702}
Harald Welte835b15f2018-02-18 14:39:11 +01001703
Harald Welte6f203162018-02-18 22:04:55 +01001704/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1705private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1706 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1707
1708 /* first perform regular attach */
1709 f_TC_attach(id);
1710 /* then activate PDP context */
1711 f_pdp_ctx_act(apars);
1712 /* then transceive a downlink PDU */
1713 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1714 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1715
1716 f_pdp_ctx_deact_mo(apars, '00'O);
1717}
1718testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1719 var BSSGP_ConnHdlr vc_conn;
1720 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001721 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 +01001722 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001723 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001724}
1725
Harald Welte57b9b7f2018-02-18 22:28:13 +01001726/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1727private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1728 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1729
1730 /* first perform regular attach */
1731 f_TC_attach(id);
1732 /* then activate PDP context */
1733 f_pdp_ctx_act(apars);
1734 /* then transceive a downlink PDU */
1735 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1736 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1737
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001738 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001739}
1740testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1741 var BSSGP_ConnHdlr vc_conn;
1742 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001743 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 +01001744 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001745 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001746}
1747
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001748/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1749private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1750 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1751 var Gtp1cUnitdata g_ud;
1752 var integer i;
1753 var OCT1 cause_regular_deact := '24'O;
1754
1755 /* first perform regular attach + PDP context act */
1756 f_TC_attach(id);
1757 f_pdp_ctx_act(apars);
1758
1759 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1760 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1761
1762 for (i := 0; i < 2; i := i+1) {
1763 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1764 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1765 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1766 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1767 }
1768 }
1769
1770 alt {
1771 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1772 setverdict(pass);
1773 }
1774 [] as_xid(apars, 0);
1775 }
1776
1777 /* Make sure second DeactPdpAccept is sent: */
1778 timer T := 2.0;
1779 T.start;
1780 alt {
1781 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1782 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1783 }
1784 [] T.timeout {
1785 setverdict(pass);
1786 }
1787 }
1788
1789 setverdict(pass);
1790}
1791testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1792 var BSSGP_ConnHdlr vc_conn;
1793 f_init();
1794 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1795 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001796 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001797}
1798
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001799/* ATTACH + ATTACH (2nd) */
1800private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1801 g_pars.t_guard := 5.0;
1802
1803 /* first perform regular attach */
1804 f_TC_attach(id);
1805
1806 /* second to perform regular attach */
1807 f_TC_attach(id);
1808}
1809
1810
1811testcase TC_attach_second_attempt() runs on test_CT {
1812 var BSSGP_ConnHdlr vc_conn;
1813 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001814 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001815 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001816 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001817}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001818
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001819private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1820 var Gtp1cUnitdata g_ud;
1821 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1822 var integer seq_nr;
1823
1824 /* first perform regular attach */
1825 f_TC_attach(id);
1826 /* then activate PDP context */
1827 f_pdp_ctx_act(apars);
1828
1829 /* Wait to receive first echo request and send initial Restart counter */
1830 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1831 BSSGP[0].clear;
1832 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1833 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1834 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1835 }
1836
1837 /* At some point next echo request not answered will timeout and SGSN
1838 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1839 timer T := 3.0 * 6.0 + 16.0;
1840 T.start;
1841 alt {
1842 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1843 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1844 setverdict(pass);
1845 }
1846 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1847 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1848 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1849 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1850 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1851 repeat;
1852 }
1853 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1854 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1855 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1856 repeat;
1857 }
1858 [] T.timeout {
1859 setverdict(fail, "BSSGP DeactPdpReq not received");
1860 mtc.stop;
1861 }
1862 [] as_xid(apars);
1863 }
1864 T.stop
1865
1866 setverdict(pass);
1867}
1868/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1869testcase TC_attach_echo_timeout() runs on test_CT {
1870 var BSSGP_ConnHdlr vc_conn;
1871 g_use_echo := true;
1872 f_init();
1873 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1874 vc_conn.done;
1875 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001876 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001877}
1878
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001879private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001880 var Gtp1cUnitdata g_ud;
1881 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1882
1883 /* first perform regular attach */
1884 f_TC_attach(id);
1885 /* Activate a pdp context against the GGSN */
1886 f_pdp_ctx_act(apars);
1887 /* Wait to receive first echo request and send initial Restart counter */
1888 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1889 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1890 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1891 }
1892 /* Wait to receive second echo request and send incremented Restart
1893 counter. This will fake a restarted GGSN, and pdp ctx allocated
1894 should be released by SGSN */
1895 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1896 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1897 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1898 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1899 }
1900 var OCT1 cause_network_failure := int2oct(38, 1)
1901 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001902 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001903 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001904 setverdict(pass);
1905 }
1906 [] as_xid(apars);
1907 }
1908 setverdict(pass);
1909}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001910/* ATTACH + trigger Recovery procedure through EchoResp */
1911testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001912 var BSSGP_ConnHdlr vc_conn;
1913 g_use_echo := true
1914 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001915 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 +02001916 vc_conn.done;
1917 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001918 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001919}
1920
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001921private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1922 var Gtp1cUnitdata g_ud;
1923 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1924 var integer seq_nr := 23;
1925 var GtpPeer peer;
1926 /* first perform regular attach */
1927 f_TC_attach(id);
1928
1929 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1930 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1931 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1932 f_pdp_ctx_act(apars, true);
1933
1934 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1935/* received. */
1936 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1937
1938 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1939 would be great to have an active pdp context here before triggering
1940 Recovery, and making sure the the DEACT request is sent by the SGSN.
1941 */
1942
1943 /* Activate a pdp context against the GGSN, send incremented Recovery
1944 IE. This should trigger the recovery path, but still this specific
1945 CTX activation should work. */
1946 apars.exp_rej_cause := omit; /* default value for tests */
1947 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1948 f_pdp_ctx_act(apars, true);
1949
1950 setverdict(pass);
1951}
1952/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1953testcase TC_attach_restart_ctr_create() runs on test_CT {
1954 var BSSGP_ConnHdlr vc_conn;
1955 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001956 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 +02001957 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001958 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001959}
1960
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001961/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1962private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1963 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1964 var integer seq_nr := 23;
1965 var GtpPeer peer;
1966 var integer i;
1967
1968 /* first perform regular attach */
1969 f_TC_attach(id);
1970 /* then activate PDP context */
1971 f_pdp_ctx_act(apars);
1972
Alexander Couzens0e510e62018-07-28 23:06:00 +02001973 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001974 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1975 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1976
1977 for (i := 0; i < 5; i := i+1) {
1978 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001979 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001980 [] as_xid(apars);
1981 }
1982 }
1983
1984 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1985
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001986 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001987 setverdict(pass);
1988}
1989testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1990 var BSSGP_ConnHdlr vc_conn;
1991 f_init();
1992 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001993 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 +02001994 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001995 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001996}
1997
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001998/* ATTACH + PDP CTX ACT dropped + retrans */
1999private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
2000 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2001 var Gtp1cUnitdata g_ud_first, g_ud_second;
2002 /* first perform regular attach */
2003 f_TC_attach(id);
2004
2005 /* then activate PDP context on the Gb side */
2006 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
2007 apars.apn, apars.pco), 0);
2008
2009 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2010 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2011 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2012 if (g_ud_first != g_ud_second) {
2013 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2014 mtc.stop;
2015 }
2016 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2017 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2018 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2019 apars.sgsn_tei_c, apars.gtp_resp_cause,
2020 apars.ggsn_tei_c, apars.ggsn_tei_u,
2021 apars.nsapi,
2022 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2023 omit, omit));
2024 }
Harald Welte955aa942019-05-03 01:29:29 +02002025 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002026
2027 /* Now the same with Deact */
2028 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2029 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2030 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2031 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2032 if (g_ud_first != g_ud_second) {
2033 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2034 mtc.stop;
2035 }
2036 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2037 BSSGP[0].clear;
2038 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2039 }
2040 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002041 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002042 setverdict(pass);
2043 }
2044 [] as_xid(apars, 0);
2045 }
2046
2047 setverdict(pass);
2048}
2049testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2050 var BSSGP_ConnHdlr vc_conn;
2051 f_init();
2052 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2053 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002054 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002055}
2056
2057/* Test that SGSN GTP response retransmit queue works fine */
2058private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2059 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2060 var integer seq_nr := 23;
2061 var Gtp1cUnitdata g_ud_first, g_ud_second;
2062 var template Gtp1cUnitdata g_delete_req;
2063 /* first perform regular attach + PDP context act */
2064 f_TC_attach(id);
2065 f_pdp_ctx_act(apars);
2066
2067 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2068 BSSGP[0].clear;
2069 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2070 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2071 GTP.send(g_delete_req);
2072 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002073 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002074 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2075 }
2076 [] as_xid(apars, 0);
2077 }
2078 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2079 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2080 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2081 mtc.stop;
2082 }
2083 };
2084
2085 /* Send duplicate DeleteCtxReq */
2086 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2087 GTP.send(g_delete_req);
2088 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2089 if (g_ud_first != g_ud_second) {
2090 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2091 mtc.stop;
2092 }
2093 }
2094
2095 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2096 * is handled differently by SGSN (expect "non-existent" cause) */
2097 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2098 GTP.send(g_delete_req);
2099 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2100 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2101 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2102 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2103 mtc.stop;
2104 }
2105 }
2106
2107 setverdict(pass);
2108}
2109testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2110 var BSSGP_ConnHdlr vc_conn;
2111 f_init();
2112 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2113 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002114 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002115}
2116
Alexander Couzens5e307b42018-05-22 18:12:20 +02002117private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2118 /* MS: perform regular attach */
2119 f_TC_attach(id);
2120
2121 /* HLR: cancel the location request */
2122 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2123 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002124
2125 /* ensure no Detach Request got received */
2126 timer T := 5.0;
2127 T.start;
2128 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002129 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002130 T.stop;
2131 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002132 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002133 }
2134 [] T.timeout {
2135 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002136 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002137 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002138 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002139 repeat;
2140 }
2141 }
2142}
2143
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002144/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2145private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2146 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2147
2148 /* first perform regular attach */
2149 f_TC_attach(id);
2150 /* then activate PDP context */
2151 f_pdp_ctx_act(apars);
2152 /* then transceive a downlink PDU */
2153 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2154
2155 /* Send Error indication as response from upload PDU and expect deact towards MS */
2156 f_pdp_ctx_deact_mt(apars, true);
2157}
2158testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2159 var BSSGP_ConnHdlr vc_conn;
2160 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002161 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 +02002162 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002163 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002164}
2165
Alexander Couzens5e307b42018-05-22 18:12:20 +02002166testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2167 /* MS <-> SGSN: GMM Attach
2168 * HLR -> SGSN: Cancel Location Request
2169 * HLR <- SGSN: Cancel Location Ack
2170 */
2171 var BSSGP_ConnHdlr vc_conn;
2172 f_init();
2173 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002174 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002175 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002176 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002177}
2178
2179
Alexander Couzensc87967a2018-05-22 16:09:54 +02002180private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2181 /* MS: perform regular attach */
2182 f_TC_attach(id);
2183
2184 /* HLR: cancel the location request */
2185 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2186 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2187 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2188
2189 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002190 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002191 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002192
2193 setverdict(pass);
2194}
2195
2196testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2197 /* MS <-> SGSN: GMM Attach
2198 * HLR -> SGSN: Cancel Location Request
2199 * HLR <- SGSN: Cancel Location Ack
2200 * MS <- SGSN: Detach Request
2201 * SGSN-> MS: Detach Complete
2202 */
2203 var BSSGP_ConnHdlr vc_conn;
2204 f_init();
2205 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002206 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002207 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002208 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002209}
2210
2211
Alexander Couzens6c47f292018-05-22 17:09:49 +02002212private function f_hlr_location_cancel_request_unknown_subscriber(
2213 charstring id,
2214 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2215
2216 /* HLR: cancel the location request */
2217 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2218
2219 /* cause 2 = IMSI_UNKNOWN */
2220 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2221
2222 setverdict(pass);
2223}
2224
2225private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002226 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002227}
2228
2229testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2230 /* HLR -> SGSN: Cancel Location Request
2231 * HLR <- SGSN: Cancel Location Error
2232 */
2233
2234 var BSSGP_ConnHdlr vc_conn;
2235 f_init();
2236 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002237 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 +02002238 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002239 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002240}
2241
2242private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002243 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002244}
2245
2246testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2247 /* HLR -> SGSN: Cancel Location Request
2248 * HLR <- SGSN: Cancel Location Error
2249 */
2250
2251 var BSSGP_ConnHdlr vc_conn;
2252 f_init();
2253 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002254 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 +02002255 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002256 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002257}
2258
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002259private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2260 f_TC_attach(id);
2261 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2262}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002263
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002264testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2265 /* MS <-> SGSN: Attach
2266 * MS -> SGSN: Detach Req (Power off)
2267 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2268 */
2269 var BSSGP_ConnHdlr vc_conn;
2270 var integer id := 33;
2271 var charstring imsi := hex2str(f_gen_imsi(id));
2272
2273 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002274 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002275 vc_conn.done;
2276
2277 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002278 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002279}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002280
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002281/* Attempt an attach, but loose the Identification Request (IMEI) */
2282private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2283 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002284 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002285
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002286 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 +02002287
2288 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002289 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002290 /* break */
2291 }
Harald Welte955aa942019-05-03 01:29:29 +02002292 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002293 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002294 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002295 repeat;
2296 }
Harald Welte955aa942019-05-03 01:29:29 +02002297 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002298 /* ignore ID REQ IMEI */
2299 count_req := count_req + 1;
2300 repeat;
2301 }
2302 }
2303 if (count_req != 5) {
2304 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002305 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002306 }
2307 setverdict(pass);
2308}
2309
2310testcase TC_attach_no_imei_response() runs on test_CT {
2311 /* MS -> SGSN: Attach Request IMSI
2312 * MS <- SGSN: Identity Request IMSI (optional)
2313 * MS -> SGSN: Identity Response IMSI (optional)
2314 * MS <- SGSN: Identity Request IMEI
2315 * MS -x SGSN: no response
2316 * MS <- SGSN: re-send: Identity Request IMEI 4x
2317 * MS <- SGSN: Attach Reject
2318 */
2319 var BSSGP_ConnHdlr vc_conn;
2320 f_init();
2321 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002322 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 +02002323 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002324 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002325}
2326
Alexander Couzens53f20562018-06-12 16:24:12 +02002327/* Attempt an attach, but loose the Identification Request (IMSI) */
2328private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2329 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002330 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002331
2332 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2333 g_pars.p_tmsi := 'c0000035'O;
2334
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002335 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 +02002336
2337 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002338 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002339 /* break */
2340 }
Harald Welte955aa942019-05-03 01:29:29 +02002341 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002342 /* ignore ID REQ IMSI */
2343 count_req := count_req + 1;
2344 repeat;
2345 }
Harald Welte955aa942019-05-03 01:29:29 +02002346 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002347 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002348 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002349 repeat;
2350 }
2351 }
2352 if (count_req != 5) {
2353 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002354 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002355 }
2356 setverdict(pass);
2357}
2358
2359testcase TC_attach_no_imsi_response() runs on test_CT {
2360 /* MS -> SGSN: Attach Request TMSI (unknown)
2361 * MS <- SGSN: Identity Request IMEI (optional)
2362 * MS -> SGSN: Identity Response IMEI (optional)
2363 * MS <- SGSN: Identity Request IMSI
2364 * MS -x SGSN: no response
2365 * MS <- SGSN: re-send: Identity Request IMSI 4x
2366 * MS <- SGSN: Attach Reject
2367 */
2368 var BSSGP_ConnHdlr vc_conn;
2369 f_init();
2370 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002371 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 +02002372 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002373 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002374}
2375
Alexander Couzenscf818962018-06-05 18:00:00 +02002376private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2377 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2378}
2379
2380testcase TC_attach_check_subscriber_list() runs on test_CT {
2381 /* MS <-> SGSN: Attach
2382 * VTY -> SGSN: Check if MS is in subscriber cache
2383 */
2384 var BSSGP_ConnHdlr vc_conn;
2385 var integer id := 34;
2386 var charstring imsi := hex2str(f_gen_imsi(id));
2387
2388 f_init();
2389 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002390 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002391 vc_conn.done;
2392
2393 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2394 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002395 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002396}
2397
Alexander Couzensf9858652018-06-07 16:14:53 +02002398private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2399 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002400 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002401
2402 /* unregister the old IMSI */
2403 f_bssgp_client_unregister(g_pars.imsi);
2404 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002405 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002406 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002407
2408 /* there is no auth */
2409 g_pars.net.expect_auth := false;
2410
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002411 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002412 f_gmm_auth();
2413 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002414 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002415 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002416 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002417 }
Harald Welte955aa942019-05-03 01:29:29 +02002418 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2419 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002420 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002421 setverdict(pass);
2422 }
2423 }
2424}
Alexander Couzens03d12242018-08-07 16:13:52 +02002425
2426private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2427
2428 f_TC_attach_closed_foreign(id);
2429 f_TC_attach_closed_imsi_added(id);
2430
2431}
2432
2433
Alexander Couzensf9858652018-06-07 16:14:53 +02002434testcase TC_attach_closed_add_vty() runs on test_CT {
2435 /* VTY-> SGSN: policy close
2436 * MS -> SGSN: Attach Request
2437 * MS <- SGSN: Identity Request IMSI
2438 * MS -> SGSN: Identity Response IMSI
2439 * MS <- SGSN: Attach Reject
2440 * VTY-> SGSN: policy imsi-acl add IMSI
2441 * MS -> SGSN: Attach Request
2442 * MS <- SGSN: Identity Request IMSI
2443 * MS -> SGSN: Identity Response IMSI
2444 * MS <- SGSN: Identity Request IMEI
2445 * MS -> SGSN: Identity Response IMEI
2446 * MS <- SGSN: Attach Accept
2447 */
2448 var BSSGP_ConnHdlr vc_conn;
2449 f_init();
2450 f_sleep(1.0);
2451 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2452 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002453 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2454 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002455 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002456 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002457 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002458 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002459}
2460
Alexander Couzens0085bd72018-06-12 19:08:44 +02002461/* Attempt an attach, but never answer a Attach Complete */
2462private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2463 var integer count_req := 0;
2464
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002465 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 +02002466 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002467 /* Expect SGSN to perform LU with HLR */
2468 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002470 timer T := 10.0;
2471 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002472 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002473 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002474 /* break */
2475 }
Harald Welte955aa942019-05-03 01:29:29 +02002476 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002477 /* ignore */
2478 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002479 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002480 repeat;
2481 }
2482 }
2483 if (count_req != 5) {
2484 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002485 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002486 }
2487 setverdict(pass);
2488}
2489
2490testcase TC_attach_check_complete_resend() runs on test_CT {
2491 /* MS -> SGSN: Attach Request IMSI
2492 * MS <- SGSN: Identity Request *
2493 * MS -> SGSN: Identity Response *
2494 * MS <- SGSN: Attach Complete 5x
2495 */
2496 var BSSGP_ConnHdlr vc_conn;
2497 f_init();
2498 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002499 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 +02002500 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002501 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002502}
2503
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002504friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002505 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002506 var PDU_DTAP_PS_MT mt;
2507 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002508
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002509 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002510 p_tmsi := g_pars.p_tmsi;
2511 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002512 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002513 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 +02002514 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002515 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2516 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2517 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002518 setverdict(pass);
2519 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002520 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2521 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2522 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002523 setverdict(pass);
2524 }
2525
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002526 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002527 setverdict(fail, "Unexpected RAU Reject");
2528 mtc.stop;
2529 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002530 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002531 setverdict(fail, "Unexpected RAU Reject");
2532 mtc.stop;
2533 }
2534
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002535 [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 +02002536 key_sts := ?)) {
2537 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2538 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002539 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002540 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002541 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002542 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2543 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002544 }
2545}
2546
Alexander Couzensbfda9212018-07-31 03:17:33 +02002547private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002548 /* first perform regular attach */
2549 f_TC_attach(id);
2550
2551 /* then send RAU */
2552 f_routing_area_update(g_pars.ra);
2553
2554 /* do another RAU */
2555 f_routing_area_update(g_pars.ra);
2556
2557 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2558}
2559
2560testcase TC_attach_rau_a_a() runs on test_CT {
2561 /* MS <-> SGSN: Successful Attach
2562 * MS -> SGSN: Routing Area Update Request
2563 * MS <- SGSN: Routing Area Update Accept
2564 * MS -> SGSN: Routing Area Update Request
2565 * MS <- SGSN: Routing Area Update Accept
2566 * MS -> SGSN: Detach (PowerOff)
2567 */
2568 var BSSGP_ConnHdlr vc_conn;
2569 f_init();
2570 f_sleep(1.0);
2571 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2572 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002573 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002574}
2575
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002576private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002577 f_TC_attach(id);
2578
2579 log("attach complete sending rau");
2580 f_routing_area_update(g_pars.ra, 0);
2581
2582 log("rau complete unregistering");
2583 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002584 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002585
2586 log("sending second RAU via different RA");
2587 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2588
2589 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2590}
2591
2592testcase TC_attach_rau_a_b() runs on test_CT {
2593 /* MS <-> SGSN: Successful Attach
2594 * MS -> SGSN: Routing Area _a_ Update Request
2595 * MS <- SGSN: Routing Area _a_ Update Accept
2596 * MS -> SGSN: Routing Area _b_ Update Request
2597 * MS <- SGSN: Routing Area _b_ Update Accept
2598 * MS -> SGSN: Detach (PowerOff)
2599 */
2600 var BSSGP_ConnHdlr vc_conn;
2601 f_init();
2602 f_sleep(1.0);
2603 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2604 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002605 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002606}
2607
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002608private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2609 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002610 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002611 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002612 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002613
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002614 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002615
2616 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002617 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002618 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2619 mtc.stop;
2620 }
Harald Welte955aa942019-05-03 01:29:29 +02002621 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002622 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002623 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002624 repeat;
2625 }
Harald Welte955aa942019-05-03 01:29:29 +02002626 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002627 /* send out a second GMM_Attach Request.
2628 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2629 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002630 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002631 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002632 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002633 }
2634 }
2635 f_sleep(1.0);
2636
2637 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2638 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002639 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002640 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002641 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002642 repeat;
2643 }
Harald Welte955aa942019-05-03 01:29:29 +02002644 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002645 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2646 mtc.stop;
2647 }
Harald Welte955aa942019-05-03 01:29:29 +02002648 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002649 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2650 mtc.stop;
2651 }
Harald Welte955aa942019-05-03 01:29:29 +02002652 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2653 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002654 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002655 setverdict(pass);
2656 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2657 }
2658 }
2659}
2660
2661testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2662 /* Testing if the SGSN ignore Attach Request with the exact same content */
2663 /* MS -> SGSN: Attach Request IMSI
2664 * MS <- SGSN: Identity Request IMSI (optional)
2665 * MS -> SGSN: Identity Response IMSI (optional)
2666 * MS <- SGSN: Identity Request IMEI
2667 * MS -> SGSN: Attach Request (2nd)
2668 * MS <- SGSN: Identity Response IMEI
2669 * MS <- SGSN: Attach Accept
2670 * MS -> SGSN: Attach Complete
2671 */
2672 var BSSGP_ConnHdlr vc_conn;
2673 f_init();
2674 f_sleep(1.0);
2675 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2676 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2677 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002678 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002679}
2680
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002681private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002682 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2683
2684 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2685
2686 /* send Attach Request */
2687 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2688 * 3G auth vectors */
2689 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2690 /* The thing is, if the solSACapability is 'omit', then the
2691 * revisionLevelIndicatior is at the wrong place! */
2692 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002693 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002694
2695 /* do the auth */
2696 var PDU_L3_MS_SGSN l3_mo;
2697 var PDU_L3_SGSN_MS l3_mt;
2698 var default di := activate(as_mm_identity());
2699
2700 var GSUP_IE auth_tuple;
2701 var template AuthenticationParameterAUTNTLV autn;
2702
2703 g_pars.vec := f_gen_auth_vec_3g();
2704 autn := {
2705 elementIdentifier := '28'O,
2706 lengthIndicator := lengthof(g_pars.vec.autn),
2707 autnValue := g_pars.vec.autn
2708 };
2709 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2710 g_pars.vec.sres,
2711 g_pars.vec.kc,
2712 g_pars.vec.ik,
2713 g_pars.vec.ck,
2714 g_pars.vec.autn,
2715 g_pars.vec.res));
2716 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2717 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2718 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2719
2720 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2721 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002722 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002723
2724 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002725 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002726
2727 /* wait for the GSUP resync request */
2728 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2729 g_pars.imsi,
2730 g_pars.vec.auts,
2731 g_pars.vec.rand));
2732
2733 /* generate new key material */
2734 g_pars.vec := f_gen_auth_vec_3g();
2735 autn := {
2736 elementIdentifier := '28'O,
2737 lengthIndicator := lengthof(g_pars.vec.autn),
2738 autnValue := g_pars.vec.autn
2739 };
2740
2741 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2742 g_pars.vec.sres,
2743 g_pars.vec.kc,
2744 g_pars.vec.ik,
2745 g_pars.vec.ck,
2746 g_pars.vec.autn,
2747 g_pars.vec.res));
2748 /* send new key material */
2749 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2750
2751 /* wait for the new Auth Request */
2752 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2753 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002754 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002755 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2756 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2757 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2758 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2759 valueField := substr(g_pars.vec.res, 0, 4)
2760 };
2761 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2762 elementIdentifier := '21'O,
2763 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2764 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2765 };
2766 l3_mo := valueof(auth_ciph_resp);
2767 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2768 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2769 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2770 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2771 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002772 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002773 deactivate(di);
2774
2775 /* Expect SGSN to perform LU with HLR */
2776 f_gmm_gsup_lu_isd();
2777
Harald Welte955aa942019-05-03 01:29:29 +02002778 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2779 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002780 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002781 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002782 setverdict(pass);
2783}
2784
2785testcase TC_attach_usim_resync() runs on test_CT {
2786 /* MS -> SGSN: Attach Request
2787 * MS <- SGSN: Identity Request IMSI
2788 * MS -> SGSN: Identity Response IMSI
2789 * MS <- SGSN: Identity Request IMEI
2790 * MS -> SGSN: Identity Response IMEI
2791 * HLR<- SGSN: SAI Request
2792 * HLR-> SGSN: SAI Response
2793 * MS <- SGSN: Auth Request
2794 * MS -> SGSN: Auth Failure (with AUTS)
2795 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2796 * HLR-> SGSN: SAI Response (new key material)
2797 * MS <- SGSN: Auth Request (new key material)
2798 * MS -> SGSN: Auth Response
2799 * MS <- SGSN: Attach Accept
2800 * MS -> SGSN: Attach Complete
2801 */
2802 var BSSGP_ConnHdlr vc_conn;
2803 f_init();
2804 f_sleep(1.0);
2805 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2806 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002807 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002808}
2809
Harald Weltea05b8072019-04-23 22:35:05 +02002810
2811/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2812private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2813 f_gmm_attach(false, false);
2814 f_sleep(1.0);
2815 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2816 /* try to detach to check if SGSN is still alive */
2817 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2818}
2819testcase TC_llc_null() runs on test_CT {
2820 var BSSGP_ConnHdlr vc_conn;
2821 f_init();
2822 f_sleep(1.0);
2823 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2824 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002825 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002826}
2827
Harald Welte645a1512019-04-23 23:18:23 +02002828/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2829private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2830 f_gmm_attach(false, false);
2831 f_sleep(1.0);
2832 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002833 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002834 setverdict(pass);
2835}
2836testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2837 var BSSGP_ConnHdlr vc_conn;
2838 f_init();
2839 f_sleep(1.0);
2840 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2841 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002842 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002843}
2844
2845/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2846private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2847 f_gmm_attach(false, false);
2848 f_sleep(1.0);
2849 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002850 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002851 setverdict(pass);
2852}
2853testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2854 var BSSGP_ConnHdlr vc_conn;
2855 f_init();
2856 f_sleep(1.0);
2857 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2858 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002859 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002860}
2861
Harald Welte2aaac1b2019-05-02 10:02:53 +02002862/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2863private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2864 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2865 var template (value) XID_Information xid;
2866 var template XID_Information xid_rx;
2867
2868 /* first perform regular attach */
2869 f_TC_attach(id);
2870 /* then activate PDP context */
2871 f_pdp_ctx_act(apars);
2872
2873 /* start MO XID */
2874 xid := { ts_XID_L3(''O) };
2875 xid_rx := { tr_XID_L3(''O) };
2876 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2877 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002878 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002879 [] as_xid(apars);
2880 }
2881 setverdict(pass);
2882}
2883testcase TC_xid_empty_l3() runs on test_CT {
2884 var BSSGP_ConnHdlr vc_conn;
2885 f_init();
2886 f_sleep(1.0);
2887 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2888 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002889 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002890}
2891
2892private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2893 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2894 var template (value) XID_Information xid;
2895 var template XID_Information xid_rx;
2896
2897 /* first perform regular attach */
2898 f_TC_attach(id);
2899 /* then activate PDP context */
2900 f_pdp_ctx_act(apars);
2901
2902 /* start MO XID */
2903 xid := { ts_XID_N201U(1234) };
2904 xid_rx := { tr_XID_N201U(1234) };
2905 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2906 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002907 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002908 [] as_xid(apars);
2909 }
2910 setverdict(pass);
2911}
2912testcase TC_xid_n201u() runs on test_CT {
2913 var BSSGP_ConnHdlr vc_conn;
2914 f_init();
2915 f_sleep(1.0);
2916 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2917 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002918 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002919}
2920
Alexander Couzens6bee0872019-05-11 01:48:50 +02002921private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2922 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2923
2924 /* first perform regular attach */
2925 f_TC_attach(id);
2926 /* then activate PDP context */
2927 f_pdp_ctx_act(apars);
2928 /* do a normal detach */
2929 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2930}
2931
2932testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2933 /* MS -> SGSN: Attach Request
2934 * MS <-> SGSN: [..]
2935 * MS -> SGSN: Attach Complete
2936 * MS -> SGSN: PDP Activate Request
2937 * MS <- SGSN: PDP Activate Accept
2938 * MS -> SGSN: GMM Detach Request
2939 * MS <- SGSN: GMM Detach Accept
2940 */
2941 var BSSGP_ConnHdlr vc_conn;
2942 f_init();
2943 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2944 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002945 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002946}
Harald Welte645a1512019-04-23 23:18:23 +02002947
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002948private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2949 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2950 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2951 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2952 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2953 var PDU_L3_SGSN_MS l3_mt;
2954
2955 f_send_l3(attach_req, 0);
2956
2957 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2958
2959 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2960 alt {
2961 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2962 setverdict(pass);
2963 }
2964 [] BSSGP[0].receive { repeat; }
2965 }
2966}
2967
2968/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2969 * See OS#3957 and OS#4245 for more information.
2970 */
2971testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2972 /*
2973 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2974 * MS <-- SGSN: Identity Request (IMEI)
2975 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2976 */
2977 var BSSGP_ConnHdlr vc_conn;
2978 f_init();
2979 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2980 vc_conn.done;
2981 f_cleanup();
2982}
2983
Harald Welte8e5932e2020-06-17 22:12:54 +02002984private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2985var PDU_BSSGP rx;
2986[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2987 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2988 mtc.stop;
2989 }
2990}
2991
2992/* SUSPEND, then DL traffic: should not pass + no paging expected */
2993private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2994 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2995 var default d;
2996
2997 /* first perform regular attach */
2998 f_TC_attach(id);
2999 /* then activate PDP context */
3000 f_pdp_ctx_act(apars);
3001 /* then transceive a downlink PDU */
3002 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3003
3004 /* now suspend GPRS */
3005 f_bssgp_suspend();
3006
3007 d := activate(as_nopaging_ps());
3008
3009 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3010 * nor any related paging requests */
3011 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3012
3013 deactivate(d);
3014}
3015testcase TC_suspend_nopaging() runs on test_CT {
3016 var BSSGP_ConnHdlr vc_conn;
3017 f_init();
3018 f_sleep(1.0);
3019 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3020 vc_conn.done;
3021 f_cleanup();
3022}
3023
3024
3025/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3026private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3027 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3028 var OCT1 susp_ref;
3029 var default d;
3030
3031 /* first perform regular attach */
3032 f_TC_attach(id);
3033 /* then activate PDP context */
3034 f_pdp_ctx_act(apars);
3035 /* then transceive a downlink PDU */
3036 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3037
3038 /* now suspend GPRS */
3039 susp_ref := f_bssgp_suspend();
3040
3041 d := activate(as_nopaging_ps());
3042
3043 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3044 * nor any related paging requests */
3045 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3046
3047 deactivate(d);
3048
3049 /* resume GPRS */
3050 f_bssgp_resume(susp_ref);
3051
3052 /* now data should be flowing again */
3053 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3054}
3055testcase TC_suspend_resume() runs on test_CT {
3056 var BSSGP_ConnHdlr vc_conn;
3057 f_init();
3058 f_sleep(1.0);
3059 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3060 vc_conn.done;
3061 f_cleanup();
3062}
3063
3064/* SUSPEND, then RAU: data expected to flow after implicit resume */
3065private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3066 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3067 var default d;
3068
3069 /* first perform regular attach */
3070 f_TC_attach(id);
3071 /* then activate PDP context */
3072 f_pdp_ctx_act(apars);
3073 /* then transceive a downlink PDU */
3074 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3075
3076 /* now suspend GPRS */
3077 f_bssgp_suspend();
3078
3079 d := activate(as_nopaging_ps());
3080
3081 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3082 * nor any related paging requests */
3083 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3084
3085 deactivate(d);
3086
3087 /* perform RAU (implicit RESUME) */
3088 f_routing_area_update(g_pars.ra);
3089
3090 /* now data should be flowing again */
3091 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3092
3093}
3094testcase TC_suspend_rau() runs on test_CT {
3095 var BSSGP_ConnHdlr vc_conn;
3096 f_init();
3097 f_sleep(1.0);
3098 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3099 vc_conn.done;
3100 f_cleanup();
3101}
3102
3103
3104/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3105private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3106 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3107 var default d;
3108
3109 /* first perform regular attach */
3110 f_TC_attach(id);
3111 /* then activate PDP context */
3112 f_pdp_ctx_act(apars);
3113 /* then transceive a downlink PDU */
3114 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3115
3116 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3117 f_sleep(5.0);
3118
3119 /* now data should be flowing again, but with PS PAGING */
3120 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3121 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3122
3123 /* FIXME: simulate paging response */
3124 /* FIXME: verify PDU actually arrives only after paging response was successful */
3125
3126}
3127testcase TC_paging_ps() runs on test_CT {
3128 var BSSGP_ConnHdlr vc_conn;
3129 f_init();
3130 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3131 f_sleep(1.0);
3132 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3133 vc_conn.done;
3134 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3135 f_cleanup();
3136}
3137
Philipp Maier7df55e02020-12-14 23:46:04 +01003138private function f_TC_bssgp_rim_dummy(charstring id) runs on BSSGP_ConnHdlr {
3139}
3140
3141/* Run a RIM single report procedure over the sgsn. Since the SGSN will only do a transparent routing of the
3142 * RIM messages this basically tests if the message is correctly transfered from one GB interface to the
3143 * other and vice versa. */
3144testcase TC_bssgp_rim_single_report() runs on test_CT {
3145 var BSSGP_ConnHdlr vc_conn;
3146 f_init();
3147 vc_conn := f_start_handler(refers(f_TC_bssgp_rim_dummy), testcasename(), g_gb, 17);
3148 vc_conn.done;
3149
3150 timer T := 2.0;
3151
3152 var template RIM_Routing_Address dst_addr;
3153 var template RIM_Routing_Address src_addr;
3154 var template RAN_Information_Request_RIM_Container req_cont;
3155 var template RAN_Information_RIM_Container res_cont;
3156 var template PDU_BSSGP bssgp_rim_pdu;
3157 var template PDU_BSSGP bssgp_rim_pdu_expect;
3158
3159 dst_addr := t_RIM_Routing_Address_cid(g_gb[1].cfg.bvc[0].cell_id);
3160 src_addr := t_RIM_Routing_Address_cid(g_gb[0].cfg.bvc[0].cell_id);
Harald Welte8e5932e2020-06-17 22:12:54 +02003161
3162
Philipp Maier7df55e02020-12-14 23:46:04 +01003163 /* Send NACC Ran information request to SGSN at GB interface #0. We epect the SGSN to forward this request
3164 * based on the cell id in dst_addr to GB interface #1. */
3165 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3166 ts_RIM_Sequence_Number(1),
3167 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3168 ts_RIM_Protocol_Version_Number(1),
3169 tsu_RAN_Information_Request_Application_Container_NACC(g_gb[1].cfg.bvc[0].cell_id),
3170 omit);
3171 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3172 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3173 req_cont);
3174 bssgp_rim_pdu_expect := tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3175 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3176 tr_RAN_Information_Request_RIM_Container);
3177 RIM[0].send(bssgp_rim_pdu);
3178 T.start;
3179 alt {
3180 [] RIM[1].receive(bssgp_rim_pdu_expect) { }
3181 [] RIM[1].receive {
3182 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3183 }
3184 [] T.timeout {
3185 setverdict(fail, "No BSSGP RIM PDU received");
3186 mtc.stop;
3187 }
3188 }
Harald Welte8e5932e2020-06-17 22:12:54 +02003189
Philipp Maier7df55e02020-12-14 23:46:04 +01003190 /* Now also emulate also the response as well and send it back on GB interface #1. Expect the result on
3191 * GB interface #0 */
3192 var octetstring si1 := '198fb100000000000000000000000000007900002b'O;
3193 var octetstring si3 := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
3194 var octetstring si13 := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
3195 var octetstring si := si1 & si3 & si13;
3196
3197 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3198 ts_RIM_Sequence_Number(2),
3199 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3200 ts_RIM_Protocol_Version_Number(1),
3201 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(g_gb[0].cfg.bvc[0].cell_id, false, 3, si)),
3202 omit);
3203 bssgp_rim_pdu := ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3204 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3205 res_cont);
3206 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3207 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3208 ?);
3209 RIM[1].send(bssgp_rim_pdu);
3210 T.start;
3211 alt {
3212 [] RIM[0].receive(bssgp_rim_pdu_expect) { }
3213 [] RIM[0].receive {
3214 setverdict(fail, "Unexpected BSSGP RIM PDU received");
3215 }
3216 [] T.timeout {
3217 setverdict(fail, "No BSSGP RIM PDU received");
3218 mtc.stop;
3219 }
3220 }
3221
3222 f_cleanup();
3223}
Harald Welte8e5932e2020-06-17 22:12:54 +02003224
Harald Welte5ac31492018-02-15 20:39:13 +01003225control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003226 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003227 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003228 execute( TC_attach_umts_aka_umts_res() );
3229 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003230 execute( TC_attach_auth_id_timeout() );
3231 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003232 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003233 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003234 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003235 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003236 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003237 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003238 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003239 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003240 execute( TC_attach_closed_add_vty(), 20.0 );
3241 execute( TC_attach_check_subscriber_list(), 20.0 );
3242 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003243 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003244 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3245 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3246 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3247 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003248 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003249 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003250 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003251 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003252 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003253 execute( TC_detach_unknown_nopoweroff() );
3254 execute( TC_detach_unknown_poweroff() );
3255 execute( TC_detach_nopoweroff() );
3256 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003257 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003258 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003259 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003260 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003261 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003262 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003263 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003264 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003265 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003266 execute( TC_attach_restart_ctr_echo() );
3267 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003268 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003269 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3270 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003271 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003272 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003273 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003274
Harald Welte2aaac1b2019-05-02 10:02:53 +02003275 execute( TC_xid_empty_l3() );
3276 execute( TC_xid_n201u() );
3277
Harald Weltea05b8072019-04-23 22:35:05 +02003278 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003279 execute( TC_llc_sabm_dm_llgmm() );
3280 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003281
Harald Welte8e5932e2020-06-17 22:12:54 +02003282 execute( TC_suspend_nopaging() );
3283 execute( TC_suspend_resume() );
3284 execute( TC_suspend_rau() );
3285 execute( TC_paging_ps() );
3286
Philipp Maier7df55e02020-12-14 23:46:04 +01003287 execute( TC_bssgp_rim_single_report() );
3288
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003289 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3290 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003291}
Harald Welte96a33b02018-02-04 10:36:22 +01003292
3293
3294
3295}