blob: 0b298bb056f140172e4319f0b709138b048842f8 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010074 handle_sns := false,
75 nsvc := {
76 {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 21010,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1"
84 }
85 },
86 nsvci := 97
87 }
88 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020089 },
90 {
Harald Welte5e514fa2018-07-05 00:01:45 +020091 nsei := 97,
92 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010093 handle_sns := false,
94 nsvc := {
95 {
96 provider := {
97 ip := {
98 address_family := AF_INET,
99 local_udp_port := 21011,
100 local_ip := "127.0.0.1",
101 remote_udp_port := 23000,
102 remote_ip := "127.0.0.1"
103 }
104 },
105 nsvci := 98
106 }
107 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200108 },
109 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200110 nsei := 98,
111 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100112 handle_sns := false,
113 nsvc := {
114 {
115 provider := {
116 ip := {
117 address_family := AF_INET,
118 local_udp_port := 21012,
119 local_ip := "127.0.0.1",
120 remote_udp_port := 23000,
121 remote_ip := "127.0.0.1"
122 }
123 },
124 nsvci := 99
125 }
126 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200127 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200128 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200129
130 RAN_Configurations mp_ranap_cfg := {
131 {
132 transport := RANAP_TRANSPORT_IuCS,
133 sccp_service_type := "mtp3_itu",
134 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
135 own_pc := 195,
136 own_ssn := 142,
137 peer_pc := 188, /* 0.23.4 */
138 peer_ssn := 142,
139 sio := '83'O,
140 rctx := 2
141 }
142 }
Harald Welte5ac31492018-02-15 20:39:13 +0100143};
144
Harald Welte5339b2e2020-10-04 22:52:56 +0200145const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100146type record GbInstance {
147 NS_CT vc_NS,
148 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200149 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100150 BssgpConfig cfg
151};
Harald Welte96a33b02018-02-04 10:36:22 +0100152
Harald Welte2fa771f2019-05-02 20:13:53 +0200153const integer NUM_GB := 3;
154type record length(NUM_GB) of GbInstance GbInstances;
155type record length(NUM_GB) of NSConfiguration NSConfigurations;
156type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200157
Harald Welte26fbb6e2019-04-14 17:32:46 +0200158const integer NUM_RNC := 1;
159type record of RAN_Configuration RAN_Configurations;
160
Harald Welte96a33b02018-02-04 10:36:22 +0100161type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200162 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200163 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200164 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100165
Harald Welte5ac31492018-02-15 20:39:13 +0100166 var GSUP_Emulation_CT vc_GSUP;
167 var IPA_Emulation_CT vc_GSUP_IPA;
168 /* only to get events from IPA underneath GSUP */
169 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100170
Harald Welte5339b2e2020-10-04 22:52:56 +0200171 /* only needed at start to get the per-BVC references */
172 port BSSGP_CT_PROC_PT PROC;
173
Harald Welteeded9ad2018-02-17 20:57:34 +0100174 var GTP_Emulation_CT vc_GTP;
175
Harald Weltebd194722018-02-16 22:11:08 +0100176 port TELNETasp_PT SGSNVTY;
177
Harald Welte96a33b02018-02-04 10:36:22 +0100178 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200179 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100180};
181
Harald Welte26fbb6e2019-04-14 17:32:46 +0200182type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100183 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100184 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200185 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100186}
187
188type record SGSN_ConnHdlrNetworkPars {
189 boolean expect_ptmsi,
190 boolean expect_auth,
191 boolean expect_ciph
192};
193
194type record BSSGP_ConnHdlrPars {
195 /* IMEI of the simulated ME */
196 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200197 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100198 hexstring imsi,
199 /* MSISDN of the simulated MS (probably unused) */
200 hexstring msisdn,
201 /* P-TMSI allocated to the simulated MS */
202 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100203 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100204 /* TLLI of the simulated MS */
205 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100206 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100207 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200208 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200209 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
210 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100211 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100212 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200213 float t_guard,
214 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200215 SCCP_PAR_Address sccp_addr_local optional,
216 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100217};
218
Alexander Couzens89508702018-07-31 04:16:10 +0200219private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200220 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200221 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
222
223 var RoutingAreaIdentificationV ret := {
224 mccDigit1 := mcc_mnc[0],
225 mccDigit2 := mcc_mnc[1],
226 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200227 mncDigit3 := mcc_mnc[3],
228 mncDigit1 := mcc_mnc[4],
229 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200230 lac := int2oct(cell_id.ra_id.lai.lac, 16),
231 rac := int2oct(cell_id.ra_id.rac, 8)
232 }
233 return ret;
234};
235
Alexander Couzens51114d12018-07-31 18:41:56 +0200236private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
237 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
238 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100239 /* connect lower end of BSSGP emulation with NS upper port */
240 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100241
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200242 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200243 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
244 /* resolve the per-BVC component references */
245 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
246 connect(self:PROC, gb.vc_BSSGP:PROC);
247 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
248 disconnect(self:PROC, gb.vc_BSSGP:PROC);
249 }
Harald Welte5ac31492018-02-15 20:39:13 +0100250}
251
252private function f_init_gsup(charstring id) runs on test_CT {
253 id := id & "-GSUP";
254 var GsupOps ops := {
255 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
256 };
257
258 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
259 vc_GSUP := GSUP_Emulation_CT.create(id);
260
261 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
262 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
263 /* we use this hack to get events like ASP_IPA_EVENT_UP */
264 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
265
266 vc_GSUP.start(GSUP_Emulation.main(ops, id));
267 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
268
269 /* wait for incoming connection to GSUP port before proceeding */
270 timer T := 10.0;
271 T.start;
272 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700273 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100274 [] T.timeout {
275 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200276 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100277 }
278 }
279}
280
Harald Welteeded9ad2018-02-17 20:57:34 +0100281private function f_init_gtp(charstring id) runs on test_CT {
282 id := id & "-GTP";
283
284 var GtpEmulationCfg gtp_cfg := {
285 gtpc_bind_ip := mp_ggsn_ip,
286 gtpc_bind_port := GTP1C_PORT,
287 gtpu_bind_ip := mp_ggsn_ip,
288 gtpu_bind_port := GTP1U_PORT,
289 sgsn_role := false
290 };
291
292 vc_GTP := GTP_Emulation_CT.create(id);
293 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
294}
295
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200296friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100297 map(self:SGSNVTY, system:SGSNVTY);
298 f_vty_set_prompts(SGSNVTY);
299 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200300 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100301 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
302}
303
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200304private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
305 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200306 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200307 } else {
308 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
309 }
310}
311
Harald Weltebd194722018-02-16 22:11:08 +0100312
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200313/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
314function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200315 var integer i;
316
Harald Welte96a33b02018-02-04 10:36:22 +0100317 if (g_initialized == true) {
318 return;
319 }
320 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100321 g_gb[0].cfg := {
322 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200323 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200324 bvc := {
325 {
326 bvci := 196,
327 cell_id := {
328 ra_id := {
329 lai := {
330 mcc_mnc := mcc_mnc,
331 lac := 13135
332 },
333 rac := 0
334 },
335 cell_id := 20960
336 },
Harald Welte4d112c92020-11-12 19:48:31 +0100337 depth := BSSGP_DECODE_DEPTH_L3,
338 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200339 }
340 }
Harald Welte5ac31492018-02-15 20:39:13 +0100341 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200342 g_gb[1].cfg := {
343 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200344 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200345 bvc := {
346 {
347 bvci := 210,
348 cell_id := {
349 ra_id := {
350 lai := {
351 mcc_mnc := mcc_mnc,
352 lac := 13200
353 },
354 rac := 0
355 },
356 cell_id := 20961
357 },
Harald Welte4d112c92020-11-12 19:48:31 +0100358 depth := BSSGP_DECODE_DEPTH_L3,
359 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200360 }
361 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200362 };
363 g_gb[2].cfg := {
364 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200365 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200366 bvc := {
367 {
368 bvci := 220,
369 cell_id := {
370 ra_id := {
371 lai := {
372 mcc_mnc := mcc_mnc,
373 lac := 13300
374 },
375 rac := 0
376 },
377 cell_id := 20962
378 },
Harald Welte4d112c92020-11-12 19:48:31 +0100379 depth := BSSGP_DECODE_DEPTH_L3,
380 create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
Harald Welte5339b2e2020-10-04 22:52:56 +0200381 }
382 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200383 };
Harald Welte96a33b02018-02-04 10:36:22 +0100384
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200385 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200386 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
387 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
388 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200389
Alexander Couzens1552e792019-07-23 20:38:39 +0200390 if (g_ranap_enable) {
391 for (i := 0; i < NUM_RNC; i := i+1) {
392 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
393 f_ran_adapter_start(g_ranap[i]);
394 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200395 }
Harald Welte5ac31492018-02-15 20:39:13 +0100396 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100397 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200398 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100399}
Harald Welte96a33b02018-02-04 10:36:22 +0100400
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200401function f_cleanup() runs on test_CT {
402 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200403 if (g_ranap_enable) {
404 for (i := 0; i < NUM_RNC; i := i+1) {
405 f_ran_adapter_cleanup(g_ranap[i]);
406 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200407 }
408 self.stop;
409}
410
Harald Welte26fbb6e2019-04-14 17:32:46 +0200411private function RncUnitdataCallback(RANAP_PDU ranap)
412runs on RAN_Emulation_CT return template RANAP_PDU {
413 var template RANAP_PDU resp := omit;
414
415 log ("RANAP_RncUnitDataCallback");
416 /* answer all RESET with RESET ACK */
417 if (match(ranap, tr_RANAP_Reset)) {
418 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
419 var CN_DomainIndicator dom;
420 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
421 resp := ts_RANAP_ResetAck(dom);
422 }
423 return resp;
424}
425
426const RanOps RNC_RanOps := {
427 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
428 ranap_unitdata_cb := refers(RncUnitdataCallback),
429 ps_domain := true,
430 decode_dtap := true,
431 role_ms := true,
432 protocol := RAN_PROTOCOL_RANAP,
433 transport := RANAP_TRANSPORT_IuCS,
434 use_osmux := false,
435 sccp_addr_local := omit,
436 sccp_addr_peer := omit
437};
438
Harald Welte5ac31492018-02-15 20:39:13 +0100439type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
440
441/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200442function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100443 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100444runs on test_CT return BSSGP_ConnHdlr {
445 var BSSGP_ConnHdlr vc_conn;
446 var SGSN_ConnHdlrNetworkPars net_pars := {
447 expect_ptmsi := true,
448 expect_auth := true,
449 expect_ciph := false
450 };
451 var BSSGP_ConnHdlrPars pars := {
452 imei := f_gen_imei(imsi_suffix),
453 imsi := f_gen_imsi(imsi_suffix),
454 msisdn := f_gen_msisdn(imsi_suffix),
455 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100456 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100457 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100458 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100459 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200460 bssgp_cell_id := {
461 gb[0].cfg.bvc[0].cell_id,
462 gb[1].cfg.bvc[0].cell_id,
463 gb[2].cfg.bvc[0].cell_id
464 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200465 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100466 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100467 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200468 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200469 sccp_addr_local := omit,
470 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100471 };
472
Alexander Couzens1552e792019-07-23 20:38:39 +0200473 if (g_ranap_enable) {
474 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
475 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
476 }
477
Harald Welte5ac31492018-02-15 20:39:13 +0100478 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200479
480 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
481 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
482 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
483
484 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
485 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
486 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
487
488 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
489 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
490 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100491
Harald Welte26fbb6e2019-04-14 17:32:46 +0200492 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200493 if (g_ranap_enable) {
494 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
495 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
496 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200497
Harald Welte5ac31492018-02-15 20:39:13 +0100498 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
499 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
500
Harald Welteeded9ad2018-02-17 20:57:34 +0100501 connect(vc_conn:GTP, vc_GTP:CLIENT);
502 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
503
Harald Welte5ac31492018-02-15 20:39:13 +0100504 vc_conn.start(f_handler_init(fn, id, pars));
505 return vc_conn;
506}
507
Harald Welte62e29582018-02-16 21:17:11 +0100508private altstep as_Tguard() runs on BSSGP_ConnHdlr {
509 [] g_Tguard.timeout {
510 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200511 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100512 }
513}
514
Harald Welte5ac31492018-02-15 20:39:13 +0100515/* first function called in every ConnHdlr */
516private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
517runs on BSSGP_ConnHdlr {
518 /* do some common stuff like setting up g_pars */
519 g_pars := pars;
520
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200521 llc := f_llc_create(false);
522
Harald Welte5ac31492018-02-15 20:39:13 +0100523 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200524 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100525 /* tell GSUP dispatcher to send this IMSI to us */
526 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100527 /* tell GTP dispatcher to send this IMSI to us */
528 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100529
Harald Welte62e29582018-02-16 21:17:11 +0100530 g_Tguard.start(pars.t_guard);
531 activate(as_Tguard());
532
Harald Welte5ac31492018-02-15 20:39:13 +0100533 /* call the user-supplied test case function */
534 fn.apply(id);
535 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100536}
537
538/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100539 * Detach without Attach
540 * SM procedures without attach / RAU
541 * ATTACH / RAU
542 ** with / without authentication
543 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100544 * re-transmissions of LLC frames
545 * PDP Context activation
546 ** with different GGSN config in SGSN VTY
547 ** with different PDP context type (v4/v6/v46)
548 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100549 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100550 */
551
552testcase TC_wait_ns_up() runs on test_CT {
553 f_init();
554 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200555 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100556}
557
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200558friend function is_gb(integer ran_index) return boolean {
559 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200560}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200561friend function is_iu(integer ran_index) return boolean {
562 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200563}
564
Alexander Couzens0507ec32019-09-15 22:41:22 +0200565function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200566 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200567 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 +0200568}
569
Alexander Couzens0507ec32019-09-15 22:41:22 +0200570private 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 +0200571 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
572 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
573 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200574 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200575}
576
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200577/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
578function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
579 log("Sending InitialUE: ", l3_mo);
580 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
581 var RANAP_PDU ranap;
582 var LAI lai := {
583 pLMNidentity := '62F224'O,
584 lAC := '1234'O,
585 iE_Extensions := omit
586 };
587 var SAI sai := {
588 pLMNidentity := lai.pLMNidentity,
589 lAC := lai.lAC,
590 sAC := '0000'O, /* FIXME */
591 iE_Extensions := omit
592 };
593 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
594 var GlobalRNC_ID grnc_id := {
595 pLMNidentity := lai.pLMNidentity,
596 rNC_ID := 2342 /* FIXME */
597 };
598
599 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
600 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
601 alt {
602 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
603 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
604 setverdict(fail, "DISC.ind from SCCP");
605 mtc.stop;
606 }
607 }
608}
609
610/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200611function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
612 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200613 if (g_pars.rnc_send_initial_ue) {
614 g_pars.rnc_send_initial_ue := false;
615 f_send_l3_initial_ue(l3_mo);
616 } else {
617 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
618 }
619 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200620 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200621 }
622}
623
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200624altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700625 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200626 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100627 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200628 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100629 repeat;
630 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200631 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200632 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200633 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200634 repeat;
635 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200636 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100637 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200638 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200639 repeat;
640 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200641 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200642 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200643 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100644 repeat;
645 }
646}
Harald Welte96a33b02018-02-04 10:36:22 +0100647
Harald Welteca362462019-05-02 20:11:21 +0200648/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200649function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200650runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200651 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200652 var PDU_L3_SGSN_MS l3_mt;
653 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200654 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
655 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200656 l3_mt := mt.dtap;
657 }
Harald Welteca362462019-05-02 20:11:21 +0200658 }
659 return l3_mt;
660}
661
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200662/* perform GMM authentication (if expected).
663 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
664 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200665function 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 +0100666 var PDU_L3_MS_SGSN l3_mo;
667 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200668 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100669 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200670 var GSUP_IE auth_tuple;
671 var template AuthenticationParameterAUTNTLV autn;
672
673 if (umts_aka_challenge) {
674 g_pars.vec := f_gen_auth_vec_3g();
675 autn := {
676 elementIdentifier := '28'O,
677 lengthIndicator := lengthof(g_pars.vec.autn),
678 autnValue := g_pars.vec.autn
679 };
680
681 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
682 g_pars.vec.sres,
683 g_pars.vec.kc,
684 g_pars.vec.ik,
685 g_pars.vec.ck,
686 g_pars.vec.autn,
687 g_pars.vec.res));
688 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
689 } else {
690 g_pars.vec := f_gen_auth_vec_2g();
691 autn := omit;
692 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
693 g_pars.vec.sres,
694 g_pars.vec.kc));
695 log("GSUP sends only 2G auth tuple", auth_tuple);
696 }
Harald Welteca362462019-05-02 20:11:21 +0200697
Harald Welte5ac31492018-02-15 20:39:13 +0100698 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
699 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200700
701 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
702 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200703 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100704 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200705 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
706
707 if (umts_aka_challenge and not force_gsm_sres) {
708 /* set UMTS response instead */
709 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
710 valueField := substr(g_pars.vec.res, 0, 4)
711 };
712 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
713 elementIdentifier := '21'O,
714 lengthIndicator := lengthof(g_pars.vec.res) - 4,
715 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
716 };
717 }
718
719 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100720 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
721 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
722 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
723 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
724 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200725 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200726
727 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200728 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200729 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
730 key_sts := ?)) {
731 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
732 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200733 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200734 }
735 }
Harald Welte76dee092018-02-16 22:12:59 +0100736 } else {
737 /* wait for identity procedure */
738 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100739 }
Harald Welte76dee092018-02-16 22:12:59 +0100740
Harald Welte5ac31492018-02-15 20:39:13 +0100741 deactivate(di);
742}
743
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200744function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100745 g_pars.p_tmsi := p_tmsi;
746 /* update TLLI */
747 g_pars.tlli_old := g_pars.tlli;
748 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100749 if (is_gb(ran_index)) {
750 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
751 }
Harald Weltef70997d2018-02-17 10:11:19 +0100752}
753
Harald Welte04683d02018-02-16 22:43:45 +0100754function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
755 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100756 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200757 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100758 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200759 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200760 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100761 }
Harald Welte04683d02018-02-16 22:43:45 +0100762 g_pars.ra := aa.routingAreaIdentification;
763 if (ispresent(aa.allocatedPTMSI)) {
764 if (not g_pars.net.expect_ptmsi) {
765 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200766 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100767 }
Harald Weltef70997d2018-02-17 10:11:19 +0100768 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100769 }
770 if (ispresent(aa.msIdentity)) {
771 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200772 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100773 }
774 /* P-TMSI.sig */
775 if (ispresent(aa.ptmsiSignature)) {
776 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
777 }
778 /* updateTimer */
779 // aa.readyTimer
780 /* T3302, T3319, T3323, T3312_ext, T3324 */
781}
782
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200783function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100784 /* mandatory IE */
785 g_pars.ra := ra.routingAreaId;
786 if (ispresent(ra.allocatedPTMSI)) {
787 if (not g_pars.net.expect_ptmsi) {
788 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200789 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100790 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200791 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100792 }
793 if (ispresent(ra.msIdentity)) {
794 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200795 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100796 }
797 /* P-TMSI.sig */
798 if (ispresent(ra.ptmsiSignature)) {
799 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
800 }
801 /* updateTimer */
802 // aa.readyTimer
803 /* T3302, T3319, T3323, T3312_ext, T3324 */
804}
805
806
Harald Welte5a4fa042018-02-16 20:59:21 +0100807function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
808 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
809}
810
Harald Welte23178c52018-02-17 09:36:33 +0100811/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700812private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100813 if (ispresent(g_pars.p_tmsi)) {
814 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
815 } else {
816 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
817 }
818}
819
Harald Welte311ec272018-02-17 09:40:03 +0100820private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100821 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100822 /* Expect MSC to perform LU with HLR */
823 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100824 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
825 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
826 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100827 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
828 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
829}
830
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200831friend 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 +0100832 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200833 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 +0200834 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100835
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200836 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
837 * 3G auth vectors */
838 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
839 /* The thing is, if the solSACapability is 'omit', then the
840 * revisionLevelIndicatior is at the wrong place! */
841 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
842
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200843 f_send_l3(attach_req, ran_index);
844 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200845 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100846 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100847
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200848 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200849 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
850
Harald Welte04683d02018-02-16 22:43:45 +0100851 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200852 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200853
854 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200855 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200856 as_iu_release_compl_disc();
857 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200858
859 /* Race condition
860 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
861 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
862 * arrived before it. This results in a test case failure.
863 * Delay execution by 50 ms
864 */
865 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200866}
867
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200868friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
869 timer T := 5.0;
870 var PDU_BSSGP rx_pdu;
871 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
872 T.start;
873 alt {
874 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
875 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
876 }
877 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
878 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
879 mtc.stop;
880 }
881 [] T.timeout {
882 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
883 mtc.stop;
884 }
885 }
886 return '00'O;
887}
888
889friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
890 timer T := 5.0;
891 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
892 T.start;
893 alt {
894 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
895 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
896?)) {
897 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
898 mtc.stop;
899 }
900 [] T.timeout {
901 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
902 mtc.stop;
903 }
904 }
905}
906
907
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200908private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
909 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100910 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100911}
912
913testcase TC_attach() runs on test_CT {
914 var BSSGP_ConnHdlr vc_conn;
915 f_init();
916 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200917 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100918 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200919 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100920}
921
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100922testcase TC_attach_mnc3() runs on test_CT {
923 var BSSGP_ConnHdlr vc_conn;
924 f_init('023042'H);
925 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200926 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100927 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200928 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100929}
930
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200931private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
932 f_gmm_attach(true, false);
933 setverdict(pass);
934}
935testcase TC_attach_umts_aka_umts_res() runs on test_CT {
936 var BSSGP_ConnHdlr vc_conn;
937 f_init();
938 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200939 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200940 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200941 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200942}
943
944private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
945 f_gmm_attach(true, true);
946 setverdict(pass);
947}
948testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
949 var BSSGP_ConnHdlr vc_conn;
950 f_init();
951 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200952 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200953 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200954 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200955}
956
Harald Welte5b7c8122018-02-16 21:48:17 +0100957/* MS never responds to ID REQ, expect ATTACH REJECT */
958private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100959 var RoutingAreaIdentificationV old_ra := f_random_RAI();
960
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200961 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100962 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200963 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100964 /* don't send ID Response */
965 repeat;
966 }
Harald Welte955aa942019-05-03 01:29:29 +0200967 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100968 setverdict(pass);
969 }
Harald Welte955aa942019-05-03 01:29:29 +0200970 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100971 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200972 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100973 }
974 }
975}
976testcase TC_attach_auth_id_timeout() runs on test_CT {
977 var BSSGP_ConnHdlr vc_conn;
978 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200979 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 +0100980 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200981 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100982}
983
984/* HLR never responds to SAI REQ, expect ATTACH REJECT */
985private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100986 var RoutingAreaIdentificationV old_ra := f_random_RAI();
987
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200988 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100989 alt {
990 [] as_mm_identity();
991 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
992 }
993 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200994 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100995 setverdict(pass);
996}
997testcase TC_attach_auth_sai_timeout() runs on test_CT {
998 var BSSGP_ConnHdlr vc_conn;
999 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001000 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +01001001 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001002 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001003}
1004
Harald Weltefe253882018-02-17 09:25:00 +01001005/* HLR rejects SAI, expect ATTACH REJECT */
1006private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001007 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1008
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001009 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001010 alt {
1011 [] as_mm_identity();
1012 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1013 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1014 }
1015 }
Harald Welte955aa942019-05-03 01:29:29 +02001016 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001017 setverdict(pass);
1018}
1019testcase TC_attach_auth_sai_reject() runs on test_CT {
1020 var BSSGP_ConnHdlr vc_conn;
1021 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001022 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001023 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001024 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001025}
1026
Harald Welte5b7c8122018-02-16 21:48:17 +01001027/* HLR never responds to UL REQ, expect ATTACH REJECT */
1028private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001029 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001030 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1031
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001032 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001033 f_gmm_auth();
1034 /* Expect MSC to perform LU with HLR */
1035 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1036 /* Never follow-up with ISD_REQ or UL_RES */
1037 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001038 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001039 setverdict(pass);
1040 }
Harald Welte955aa942019-05-03 01:29:29 +02001041 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1042 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001043 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001044 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001045 }
1046 }
1047}
1048testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1049 var BSSGP_ConnHdlr vc_conn;
1050 f_init();
1051 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001052 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001053 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001054 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001055}
1056
Harald Welteb7c14e92018-02-17 09:29:16 +01001057/* HLR rejects UL REQ, expect ATTACH REJECT */
1058private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001059 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001060 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1061
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001062 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001063 f_gmm_auth();
1064 /* Expect MSC to perform LU with HLR */
1065 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1066 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1067 }
1068 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001069 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001070 setverdict(pass);
1071 }
Harald Welte955aa942019-05-03 01:29:29 +02001072 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1073 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001074 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001075 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001076 }
1077 }
1078}
1079testcase TC_attach_gsup_lu_reject() runs on test_CT {
1080 var BSSGP_ConnHdlr vc_conn;
1081 f_init();
1082 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001083 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001084 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001085 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001086}
1087
1088
Harald Welte3823e2e2018-02-16 21:53:48 +01001089/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1090private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001091 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001092 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1093
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001094 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001095 f_gmm_auth();
1096 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001097 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001098
Harald Welte955aa942019-05-03 01:29:29 +02001099 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1100 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001101 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001102 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001103 setverdict(pass);
1104}
Harald Welte3823e2e2018-02-16 21:53:48 +01001105testcase TC_attach_combined() runs on test_CT {
1106 var BSSGP_ConnHdlr vc_conn;
1107 f_init();
1108 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001109 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001110 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001111 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001112}
1113
Harald Welte76dee092018-02-16 22:12:59 +01001114/* Attempt of GPRS ATTACH in 'accept all' mode */
1115private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001116 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001117 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1118
1119 g_pars.net.expect_auth := false;
1120
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001121 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001122 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001123 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1124 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001125 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001126 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001127 setverdict(pass);
1128}
1129testcase TC_attach_accept_all() runs on test_CT {
1130 var BSSGP_ConnHdlr vc_conn;
1131 f_init();
1132 f_sleep(1.0);
1133 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001134 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001135 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001136 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001137}
Harald Welte5b7c8122018-02-16 21:48:17 +01001138
Harald Welteb2124b22018-02-16 22:26:56 +01001139/* Attempt of GPRS ATTACH in 'accept all' mode */
1140private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001141 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1142
1143 /* Simulate a foreign IMSI */
1144 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001145 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001146
1147 g_pars.net.expect_auth := false;
1148
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001149 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001150 alt {
1151 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001152 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001153 setverdict(pass);
1154 }
Harald Welte955aa942019-05-03 01:29:29 +02001155 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001156 setverdict(pass);
1157 }
Harald Welte955aa942019-05-03 01:29:29 +02001158 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001159 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001160 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001161 }
Harald Welteb2124b22018-02-16 22:26:56 +01001162 }
1163}
1164testcase TC_attach_closed() runs on test_CT {
1165 var BSSGP_ConnHdlr vc_conn;
1166 f_init();
1167 f_sleep(1.0);
1168 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1169 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001170 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001171 vc_conn.done;
1172 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001173 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001174 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001175 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001176}
1177
Harald Welte04683d02018-02-16 22:43:45 +01001178/* Routing Area Update from Unknown TLLI -> REJECT */
1179private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001180 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1181
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001182 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 +01001183 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001184 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001185 setverdict(pass);
1186 }
1187 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001188 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001189 }
1190}
1191testcase TC_rau_unknown() runs on test_CT {
1192 var BSSGP_ConnHdlr vc_conn;
1193 f_init();
1194 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001195 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001196 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001197 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001198}
1199
Harald Welte91636de2018-02-17 10:16:14 +01001200private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001201 /* first perform regular attach */
1202 f_TC_attach(id);
1203
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001204 f_routing_area_update(g_pars.ra);
1205
Harald Welte91636de2018-02-17 10:16:14 +01001206}
1207testcase TC_attach_rau() runs on test_CT {
1208 var BSSGP_ConnHdlr vc_conn;
1209 f_init();
1210 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001211 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001212 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001213 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001214}
Harald Welte04683d02018-02-16 22:43:45 +01001215
Harald Welte6abb9fe2018-02-17 15:24:48 +01001216/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001217function 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 +02001218 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001219 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001220 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001221 if (expect_purge) {
1222 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1223 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1224 }
1225 T.start;
1226 alt {
1227 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1228 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001229 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001230 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001231 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001232 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001233 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001234 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001235 /* TODO: check if any PDP contexts are deactivated on network side? */
1236 }
1237 [power_off] T.timeout {
1238 setverdict(pass);
1239 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001240 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001241 g_pars.ra := omit;
1242 setverdict(pass);
1243 /* TODO: check if any PDP contexts are deactivated on network side? */
1244 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001245 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001246 if (power_off) {
1247 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1248 } else {
1249 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1250 }
1251 mtc.stop;
1252 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001253 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001254 }
1255}
1256
1257/* IMSI DETACH (non-power-off) for unknown TLLI */
1258private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1259 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1260}
1261testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1262 var BSSGP_ConnHdlr vc_conn;
1263 f_init();
1264 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001265 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001266 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001267 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001268}
1269
1270/* IMSI DETACH (power-off) for unknown TLLI */
1271private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1272 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1273}
1274testcase TC_detach_unknown_poweroff() runs on test_CT {
1275 var BSSGP_ConnHdlr vc_conn;
1276 f_init();
1277 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001278 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001279 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001280 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001281}
1282
1283/* IMSI DETACH (non-power-off) for known TLLI */
1284private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1285 /* first perform regular attach */
1286 f_TC_attach(id);
1287
1288 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1289}
1290testcase TC_detach_nopoweroff() runs on test_CT {
1291 var BSSGP_ConnHdlr vc_conn;
1292 f_init();
1293 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001294 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001295 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001296 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001297}
1298
1299/* IMSI DETACH (power-off) for known TLLI */
1300private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1301 /* first perform regular attach */
1302 f_TC_attach(id);
1303
1304 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1305}
1306testcase TC_detach_poweroff() runs on test_CT {
1307 var BSSGP_ConnHdlr vc_conn;
1308 f_init();
1309 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001310 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001311 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001312 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001313}
1314
Harald Welteeded9ad2018-02-17 20:57:34 +01001315type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001316 BIT3 tid, /* L3 Transaction ID */
1317 BIT4 nsapi, /* SNDCP NSAPI */
1318 BIT4 sapi, /* LLC SAPI */
1319 QoSV qos, /* QoS parameters */
1320 PDPAddressV addr, /* IP address */
1321 octetstring apn optional, /* APN name */
1322 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1323 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001324 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001325 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001326
Harald Welte822f9102018-02-18 20:39:06 +01001327 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1328 OCT4 ggsn_tei_u, /* GGSN TEI User */
1329 octetstring ggsn_ip_c, /* GGSN IP Control */
1330 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001331 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001332
Harald Welte822f9102018-02-18 20:39:06 +01001333 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1334 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1335 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1336 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001337};
1338
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001339
1340private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1341 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1342 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1343 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1344 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1345 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1346 f_gtp_register_teid(apars.ggsn_tei_c);
1347 f_gtp_register_teid(apars.ggsn_tei_u);
1348}
1349
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001350function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001351runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001352 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1353 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001354 var template Recovery_gtpc recovery := omit;
1355
1356 if (send_recovery) {
1357 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1358 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001359
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001360 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 +02001361 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001362 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1363 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1364 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1365 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1366 apars.sgsn_tei_c, apars.gtp_resp_cause,
1367 apars.ggsn_tei_c, apars.ggsn_tei_u,
1368 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001369 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1370 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001371 }
1372 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001373 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001374 setverdict(pass);
1375 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001376 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001377 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001378 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001379 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001380 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001381 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001382 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001383 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001384 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001385 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1386 mtc.stop;
1387 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001388 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001389 setverdict(pass);
1390 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001391 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001392 }
1393}
1394
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001395function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001396runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001397 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1398 var Gtp1cUnitdata g_ud;
1399
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001400 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001401 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1402 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001403 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001404 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1405 }
1406 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001407 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001408 setverdict(pass);
1409 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001410 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001411 }
1412}
1413
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001414function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001415runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001416 var Gtp1cUnitdata g_ud;
1417 var integer seq_nr := 23;
1418 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1419
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001420 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001421 if (error_ind) {
1422 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1423 } else {
1424 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1425 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001426
1427 timer T := 5.0;
1428 T.start;
1429
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001430 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001431 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1432 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001433 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001434 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1435 repeat;
1436 }
1437 [] T.timeout {
1438 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1439 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001440 }
1441}
1442
Harald Welte6f203162018-02-18 22:04:55 +01001443
Harald Welteeded9ad2018-02-17 20:57:34 +01001444/* Table 10.5.156/3GPP TS 24.008 */
1445template (value) QoSV t_QosDefault := {
1446 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1447 delayClass := '100'B, /* best effort */
1448 spare1 := '00'B,
1449 precedenceClass := '010'B, /* normal */
1450 spare2 := '0'B,
1451 peakThroughput := '0000'B, /* subscribed */
1452 meanThroughput := '00000'B, /* subscribed */
1453 spare3 := '000'B,
1454 deliverErroneusSDU := omit,
1455 deliveryOrder := omit,
1456 trafficClass := omit,
1457 maxSDUSize := omit,
1458 maxBitrateUplink := omit,
1459 maxBitrateDownlink := omit,
1460 sduErrorRatio := omit,
1461 residualBER := omit,
1462 trafficHandlingPriority := omit,
1463 transferDelay := omit,
1464 guaranteedBitRateUplink := omit,
1465 guaranteedBitRateDownlink := omit,
1466 sourceStatisticsDescriptor := omit,
1467 signallingIndication := omit,
1468 spare4 := omit,
1469 maxBitrateDownlinkExt := omit,
1470 guaranteedBitRateDownlinkExt := omit,
1471 maxBitrateUplinkExt := omit,
1472 guaranteedBitRateUplinkExt := omit,
1473 maxBitrateDownlinkExt2 := omit,
1474 guaranteedBitRateDownlinkExt2 := omit,
1475 maxBitrateUplinkExt2 := omit,
1476 guaranteedBitRateUplinkExt2 := omit
1477}
1478
1479/* 10.5.6.4 / 3GPP TS 24.008 */
1480template (value) PDPAddressV t_AddrIPv4dyn := {
1481 pdpTypeOrg := '0001'B, /* IETF */
1482 spare := '0000'B,
1483 pdpTypeNum := '21'O, /* IPv4 */
1484 addressInfo := omit
1485}
1486template (value) PDPAddressV t_AddrIPv6dyn := {
1487 pdpTypeOrg := '0001'B, /* IETF */
1488 spare := '0000'B,
1489 pdpTypeNum := '53'O, /* IPv6 */
1490 addressInfo := omit
1491}
1492
Harald Welte37692d82018-02-18 15:21:34 +01001493template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001494 tid := '000'B,
1495 nsapi := '0101'B, /* < 5 are reserved */
1496 sapi := '0011'B, /* 3/5/9/11 */
1497 qos := t_QosDefault,
1498 addr := t_AddrIPv4dyn,
1499 apn := omit,
1500 pco := omit,
1501 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001502 gtp_resp_cause := int2oct(128, 1),
1503 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001504
1505 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001506 ggsn_tei_c := f_rnd_octstring(4),
1507 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001508 ggsn_ip_c := f_inet_addr(ggsn_ip),
1509 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001510 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001511
Harald Welteeded9ad2018-02-17 20:57:34 +01001512 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001513 sgsn_tei_u := omit,
1514 sgsn_ip_c := omit,
1515 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001516}
1517
Harald Welte37692d82018-02-18 15:21:34 +01001518template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1519 connId := 1,
1520 remName := f_inet_ntoa(ip),
1521 remPort := GTP1U_PORT
1522}
1523
1524template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1525 connId := 1,
1526 remName := f_inet_ntoa(ip),
1527 remPort := GTP1C_PORT
1528}
1529
1530private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1531 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1532 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1533}
1534
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001535private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1536 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001537 repeat;
1538 }
1539}
1540
1541template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1542 pDU_SN_UNITDATA := {
1543 nsapi := nsapi,
1544 moreBit := ?,
1545 snPduType := '1'B,
1546 firstSegmentIndicator := ?,
1547 spareBit := ?,
1548 pcomp := ?,
1549 dcomp := ?,
1550 npduNumber := ?,
1551 segmentNumber := ?,
1552 npduNumberContinued := ?,
1553 dataSegmentSnUnitdataPdu := payload
1554 }
1555}
1556
1557/* simple case: single segment, no compression */
1558template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1559 pDU_SN_UNITDATA := {
1560 nsapi := nsapi,
1561 moreBit := '0'B,
1562 snPduType := '1'B,
1563 firstSegmentIndicator := '1'B,
1564 spareBit := '0'B,
1565 pcomp := '0000'B,
1566 dcomp := '0000'B,
1567 npduNumber := '0000'B,
1568 segmentNumber := '0000'B,
1569 npduNumberContinued := '00'O,
1570 dataSegmentSnUnitdataPdu := payload
1571 }
1572}
1573
1574/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001575private 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 +02001576runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001577 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001578 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1579 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001580 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001581 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1582 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001583 [] as_xid(apars, ran_index);
1584 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001585 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1586 [expect_fwd] T.timeout {
1587 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1588 mtc.stop;
1589 }
1590 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1591 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1592 mtc.stop;
1593 }
1594 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001595 }
1596}
1597
Harald Welte64d6b512020-06-17 16:42:00 +02001598/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001599private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001600runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001601 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1602 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1603 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001604 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001605 /* Expect PDU via GTP from SGSN on simulated GGSN */
1606 alt {
1607 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1608 }
1609}
1610
Harald Welteeded9ad2018-02-17 20:57:34 +01001611private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001612 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001613
1614 /* first perform regular attach */
1615 f_TC_attach(id);
1616
1617 f_pdp_ctx_act(apars);
1618}
1619testcase TC_attach_pdp_act() runs on test_CT {
1620 var BSSGP_ConnHdlr vc_conn;
1621 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001622 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001623 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001624 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001625}
Harald Welteb2124b22018-02-16 22:26:56 +01001626
Harald Welte835b15f2018-02-18 14:39:11 +01001627/* PDP Context activation for not-attached subscriber; expect fail */
1628private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001629 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001630 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 +01001631 apars.apn, apars.pco));
1632 alt {
1633 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001634 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001635 setverdict(pass);
1636 }
1637 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1638 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001639 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001640 }
Harald Welte955aa942019-05-03 01:29:29 +02001641 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001642 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001643 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001644 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001645 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001646 }
1647}
1648testcase TC_pdp_act_unattached() runs on test_CT {
1649 var BSSGP_ConnHdlr vc_conn;
1650 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001651 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001652 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001653 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001654}
1655
Harald Welte37692d82018-02-18 15:21:34 +01001656/* ATTACH + PDP CTX ACT + user plane traffic */
1657private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1658 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1659
1660 /* first perform regular attach */
1661 f_TC_attach(id);
1662 /* then activate PDP context */
1663 f_pdp_ctx_act(apars);
1664 /* then transceive a downlink PDU */
1665 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1666 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1667}
1668testcase TC_attach_pdp_act_user() runs on test_CT {
1669 var BSSGP_ConnHdlr vc_conn;
1670 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001671 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001672 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001673 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001674}
1675
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001676/* ATTACH + PDP CTX ACT; reject from GGSN */
1677private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1678 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1679
1680 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1681 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1682
1683 /* first perform regular attach */
1684 f_TC_attach(id);
1685 /* then activate PDP context */
1686 f_pdp_ctx_act(apars);
1687}
1688testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1689 var BSSGP_ConnHdlr vc_conn;
1690 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001691 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001692 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001693 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001694}
Harald Welte835b15f2018-02-18 14:39:11 +01001695
Harald Welte6f203162018-02-18 22:04:55 +01001696/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1697private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1698 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1699
1700 /* first perform regular attach */
1701 f_TC_attach(id);
1702 /* then activate PDP context */
1703 f_pdp_ctx_act(apars);
1704 /* then transceive a downlink PDU */
1705 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1706 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1707
1708 f_pdp_ctx_deact_mo(apars, '00'O);
1709}
1710testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1711 var BSSGP_ConnHdlr vc_conn;
1712 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001713 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 +01001714 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001715 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001716}
1717
Harald Welte57b9b7f2018-02-18 22:28:13 +01001718/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1719private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1720 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1721
1722 /* first perform regular attach */
1723 f_TC_attach(id);
1724 /* then activate PDP context */
1725 f_pdp_ctx_act(apars);
1726 /* then transceive a downlink PDU */
1727 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1728 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1729
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001730 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001731}
1732testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1733 var BSSGP_ConnHdlr vc_conn;
1734 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001735 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 +01001736 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001737 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001738}
1739
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001740/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1741private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1742 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1743 var Gtp1cUnitdata g_ud;
1744 var integer i;
1745 var OCT1 cause_regular_deact := '24'O;
1746
1747 /* first perform regular attach + PDP context act */
1748 f_TC_attach(id);
1749 f_pdp_ctx_act(apars);
1750
1751 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1752 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1753
1754 for (i := 0; i < 2; i := i+1) {
1755 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1756 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1757 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1758 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1759 }
1760 }
1761
1762 alt {
1763 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1764 setverdict(pass);
1765 }
1766 [] as_xid(apars, 0);
1767 }
1768
1769 /* Make sure second DeactPdpAccept is sent: */
1770 timer T := 2.0;
1771 T.start;
1772 alt {
1773 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1774 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1775 }
1776 [] T.timeout {
1777 setverdict(pass);
1778 }
1779 }
1780
1781 setverdict(pass);
1782}
1783testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1784 var BSSGP_ConnHdlr vc_conn;
1785 f_init();
1786 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1787 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001788 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001789}
1790
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001791/* ATTACH + ATTACH (2nd) */
1792private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1793 g_pars.t_guard := 5.0;
1794
1795 /* first perform regular attach */
1796 f_TC_attach(id);
1797
1798 /* second to perform regular attach */
1799 f_TC_attach(id);
1800}
1801
1802
1803testcase TC_attach_second_attempt() runs on test_CT {
1804 var BSSGP_ConnHdlr vc_conn;
1805 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001806 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001807 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001808 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001809}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001810
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001811private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1812 var Gtp1cUnitdata g_ud;
1813 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1814 var integer seq_nr;
1815
1816 /* first perform regular attach */
1817 f_TC_attach(id);
1818 /* then activate PDP context */
1819 f_pdp_ctx_act(apars);
1820
1821 /* Wait to receive first echo request and send initial Restart counter */
1822 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1823 BSSGP[0].clear;
1824 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1825 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1826 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1827 }
1828
1829 /* At some point next echo request not answered will timeout and SGSN
1830 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1831 timer T := 3.0 * 6.0 + 16.0;
1832 T.start;
1833 alt {
1834 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1835 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1836 setverdict(pass);
1837 }
1838 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1839 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1840 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1841 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1842 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1843 repeat;
1844 }
1845 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1846 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1847 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1848 repeat;
1849 }
1850 [] T.timeout {
1851 setverdict(fail, "BSSGP DeactPdpReq not received");
1852 mtc.stop;
1853 }
1854 [] as_xid(apars);
1855 }
1856 T.stop
1857
1858 setverdict(pass);
1859}
1860/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1861testcase TC_attach_echo_timeout() runs on test_CT {
1862 var BSSGP_ConnHdlr vc_conn;
1863 g_use_echo := true;
1864 f_init();
1865 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1866 vc_conn.done;
1867 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001868 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001869}
1870
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001871private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001872 var Gtp1cUnitdata g_ud;
1873 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1874
1875 /* first perform regular attach */
1876 f_TC_attach(id);
1877 /* Activate a pdp context against the GGSN */
1878 f_pdp_ctx_act(apars);
1879 /* Wait to receive first echo request and send initial Restart counter */
1880 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1881 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1882 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1883 }
1884 /* Wait to receive second echo request and send incremented Restart
1885 counter. This will fake a restarted GGSN, and pdp ctx allocated
1886 should be released by SGSN */
1887 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
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 var OCT1 cause_network_failure := int2oct(38, 1)
1893 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001894 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001895 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001896 setverdict(pass);
1897 }
1898 [] as_xid(apars);
1899 }
1900 setverdict(pass);
1901}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001902/* ATTACH + trigger Recovery procedure through EchoResp */
1903testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001904 var BSSGP_ConnHdlr vc_conn;
1905 g_use_echo := true
1906 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001907 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 +02001908 vc_conn.done;
1909 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001910 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001911}
1912
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001913private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1914 var Gtp1cUnitdata g_ud;
1915 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1916 var integer seq_nr := 23;
1917 var GtpPeer peer;
1918 /* first perform regular attach */
1919 f_TC_attach(id);
1920
1921 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1922 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1923 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1924 f_pdp_ctx_act(apars, true);
1925
1926 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1927/* received. */
1928 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1929
1930 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1931 would be great to have an active pdp context here before triggering
1932 Recovery, and making sure the the DEACT request is sent by the SGSN.
1933 */
1934
1935 /* Activate a pdp context against the GGSN, send incremented Recovery
1936 IE. This should trigger the recovery path, but still this specific
1937 CTX activation should work. */
1938 apars.exp_rej_cause := omit; /* default value for tests */
1939 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1940 f_pdp_ctx_act(apars, true);
1941
1942 setverdict(pass);
1943}
1944/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1945testcase TC_attach_restart_ctr_create() runs on test_CT {
1946 var BSSGP_ConnHdlr vc_conn;
1947 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001948 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 +02001949 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001950 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001951}
1952
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001953/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1954private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1955 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1956 var integer seq_nr := 23;
1957 var GtpPeer peer;
1958 var integer i;
1959
1960 /* first perform regular attach */
1961 f_TC_attach(id);
1962 /* then activate PDP context */
1963 f_pdp_ctx_act(apars);
1964
Alexander Couzens0e510e62018-07-28 23:06:00 +02001965 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001966 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1967 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1968
1969 for (i := 0; i < 5; i := i+1) {
1970 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001971 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001972 [] as_xid(apars);
1973 }
1974 }
1975
1976 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1977
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001978 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001979 setverdict(pass);
1980}
1981testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1982 var BSSGP_ConnHdlr vc_conn;
1983 f_init();
1984 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001985 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 +02001986 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001987 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001988}
1989
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001990/* ATTACH + PDP CTX ACT dropped + retrans */
1991private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1992 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1993 var Gtp1cUnitdata g_ud_first, g_ud_second;
1994 /* first perform regular attach */
1995 f_TC_attach(id);
1996
1997 /* then activate PDP context on the Gb side */
1998 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1999 apars.apn, apars.pco), 0);
2000
2001 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
2002 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2003 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2004 if (g_ud_first != g_ud_second) {
2005 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2006 mtc.stop;
2007 }
2008 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2009 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2010 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2011 apars.sgsn_tei_c, apars.gtp_resp_cause,
2012 apars.ggsn_tei_c, apars.ggsn_tei_u,
2013 apars.nsapi,
2014 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2015 omit, omit));
2016 }
Harald Welte955aa942019-05-03 01:29:29 +02002017 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002018
2019 /* Now the same with Deact */
2020 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2021 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2022 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2023 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2024 if (g_ud_first != g_ud_second) {
2025 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2026 mtc.stop;
2027 }
2028 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2029 BSSGP[0].clear;
2030 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2031 }
2032 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002033 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002034 setverdict(pass);
2035 }
2036 [] as_xid(apars, 0);
2037 }
2038
2039 setverdict(pass);
2040}
2041testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2042 var BSSGP_ConnHdlr vc_conn;
2043 f_init();
2044 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2045 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002046 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002047}
2048
2049/* Test that SGSN GTP response retransmit queue works fine */
2050private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2051 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2052 var integer seq_nr := 23;
2053 var Gtp1cUnitdata g_ud_first, g_ud_second;
2054 var template Gtp1cUnitdata g_delete_req;
2055 /* first perform regular attach + PDP context act */
2056 f_TC_attach(id);
2057 f_pdp_ctx_act(apars);
2058
2059 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2060 BSSGP[0].clear;
2061 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2062 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2063 GTP.send(g_delete_req);
2064 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002065 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002066 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2067 }
2068 [] as_xid(apars, 0);
2069 }
2070 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2071 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2072 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2073 mtc.stop;
2074 }
2075 };
2076
2077 /* Send duplicate DeleteCtxReq */
2078 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2079 GTP.send(g_delete_req);
2080 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2081 if (g_ud_first != g_ud_second) {
2082 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2083 mtc.stop;
2084 }
2085 }
2086
2087 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2088 * is handled differently by SGSN (expect "non-existent" cause) */
2089 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2090 GTP.send(g_delete_req);
2091 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2092 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2093 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2094 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2095 mtc.stop;
2096 }
2097 }
2098
2099 setverdict(pass);
2100}
2101testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2102 var BSSGP_ConnHdlr vc_conn;
2103 f_init();
2104 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2105 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002106 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002107}
2108
Alexander Couzens5e307b42018-05-22 18:12:20 +02002109private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2110 /* MS: perform regular attach */
2111 f_TC_attach(id);
2112
2113 /* HLR: cancel the location request */
2114 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2115 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002116
2117 /* ensure no Detach Request got received */
2118 timer T := 5.0;
2119 T.start;
2120 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002121 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002122 T.stop;
2123 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002124 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002125 }
2126 [] T.timeout {
2127 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002128 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002129 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002130 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002131 repeat;
2132 }
2133 }
2134}
2135
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002136/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2137private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2138 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2139
2140 /* first perform regular attach */
2141 f_TC_attach(id);
2142 /* then activate PDP context */
2143 f_pdp_ctx_act(apars);
2144 /* then transceive a downlink PDU */
2145 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2146
2147 /* Send Error indication as response from upload PDU and expect deact towards MS */
2148 f_pdp_ctx_deact_mt(apars, true);
2149}
2150testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2151 var BSSGP_ConnHdlr vc_conn;
2152 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002153 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 +02002154 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002155 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002156}
2157
Alexander Couzens5e307b42018-05-22 18:12:20 +02002158testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2159 /* MS <-> SGSN: GMM Attach
2160 * HLR -> SGSN: Cancel Location Request
2161 * HLR <- SGSN: Cancel Location Ack
2162 */
2163 var BSSGP_ConnHdlr vc_conn;
2164 f_init();
2165 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002166 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002167 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002168 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002169}
2170
2171
Alexander Couzensc87967a2018-05-22 16:09:54 +02002172private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2173 /* MS: perform regular attach */
2174 f_TC_attach(id);
2175
2176 /* HLR: cancel the location request */
2177 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2178 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2179 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2180
2181 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002182 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002183 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002184
2185 setverdict(pass);
2186}
2187
2188testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2189 /* MS <-> SGSN: GMM Attach
2190 * HLR -> SGSN: Cancel Location Request
2191 * HLR <- SGSN: Cancel Location Ack
2192 * MS <- SGSN: Detach Request
2193 * SGSN-> MS: Detach Complete
2194 */
2195 var BSSGP_ConnHdlr vc_conn;
2196 f_init();
2197 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002198 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002199 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002200 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002201}
2202
2203
Alexander Couzens6c47f292018-05-22 17:09:49 +02002204private function f_hlr_location_cancel_request_unknown_subscriber(
2205 charstring id,
2206 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2207
2208 /* HLR: cancel the location request */
2209 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2210
2211 /* cause 2 = IMSI_UNKNOWN */
2212 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2213
2214 setverdict(pass);
2215}
2216
2217private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002218 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002219}
2220
2221testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2222 /* HLR -> SGSN: Cancel Location Request
2223 * HLR <- SGSN: Cancel Location Error
2224 */
2225
2226 var BSSGP_ConnHdlr vc_conn;
2227 f_init();
2228 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002229 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 +02002230 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002231 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002232}
2233
2234private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002235 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002236}
2237
2238testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2239 /* HLR -> SGSN: Cancel Location Request
2240 * HLR <- SGSN: Cancel Location Error
2241 */
2242
2243 var BSSGP_ConnHdlr vc_conn;
2244 f_init();
2245 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002246 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 +02002247 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002248 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002249}
2250
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002251private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2252 f_TC_attach(id);
2253 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2254}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002255
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002256testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2257 /* MS <-> SGSN: Attach
2258 * MS -> SGSN: Detach Req (Power off)
2259 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2260 */
2261 var BSSGP_ConnHdlr vc_conn;
2262 var integer id := 33;
2263 var charstring imsi := hex2str(f_gen_imsi(id));
2264
2265 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002266 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002267 vc_conn.done;
2268
2269 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002270 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002271}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002272
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002273/* Attempt an attach, but loose the Identification Request (IMEI) */
2274private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2275 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002276 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002277
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002278 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 +02002279
2280 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002281 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002282 /* break */
2283 }
Harald Welte955aa942019-05-03 01:29:29 +02002284 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002285 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002286 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002287 repeat;
2288 }
Harald Welte955aa942019-05-03 01:29:29 +02002289 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002290 /* ignore ID REQ IMEI */
2291 count_req := count_req + 1;
2292 repeat;
2293 }
2294 }
2295 if (count_req != 5) {
2296 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002297 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002298 }
2299 setverdict(pass);
2300}
2301
2302testcase TC_attach_no_imei_response() runs on test_CT {
2303 /* MS -> SGSN: Attach Request IMSI
2304 * MS <- SGSN: Identity Request IMSI (optional)
2305 * MS -> SGSN: Identity Response IMSI (optional)
2306 * MS <- SGSN: Identity Request IMEI
2307 * MS -x SGSN: no response
2308 * MS <- SGSN: re-send: Identity Request IMEI 4x
2309 * MS <- SGSN: Attach Reject
2310 */
2311 var BSSGP_ConnHdlr vc_conn;
2312 f_init();
2313 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002314 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 +02002315 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002316 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002317}
2318
Alexander Couzens53f20562018-06-12 16:24:12 +02002319/* Attempt an attach, but loose the Identification Request (IMSI) */
2320private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2321 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002322 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002323
2324 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2325 g_pars.p_tmsi := 'c0000035'O;
2326
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002327 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 +02002328
2329 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002330 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002331 /* break */
2332 }
Harald Welte955aa942019-05-03 01:29:29 +02002333 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002334 /* ignore ID REQ IMSI */
2335 count_req := count_req + 1;
2336 repeat;
2337 }
Harald Welte955aa942019-05-03 01:29:29 +02002338 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002339 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002340 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002341 repeat;
2342 }
2343 }
2344 if (count_req != 5) {
2345 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002346 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002347 }
2348 setverdict(pass);
2349}
2350
2351testcase TC_attach_no_imsi_response() runs on test_CT {
2352 /* MS -> SGSN: Attach Request TMSI (unknown)
2353 * MS <- SGSN: Identity Request IMEI (optional)
2354 * MS -> SGSN: Identity Response IMEI (optional)
2355 * MS <- SGSN: Identity Request IMSI
2356 * MS -x SGSN: no response
2357 * MS <- SGSN: re-send: Identity Request IMSI 4x
2358 * MS <- SGSN: Attach Reject
2359 */
2360 var BSSGP_ConnHdlr vc_conn;
2361 f_init();
2362 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002363 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 +02002364 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002365 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002366}
2367
Alexander Couzenscf818962018-06-05 18:00:00 +02002368private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2369 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2370}
2371
2372testcase TC_attach_check_subscriber_list() runs on test_CT {
2373 /* MS <-> SGSN: Attach
2374 * VTY -> SGSN: Check if MS is in subscriber cache
2375 */
2376 var BSSGP_ConnHdlr vc_conn;
2377 var integer id := 34;
2378 var charstring imsi := hex2str(f_gen_imsi(id));
2379
2380 f_init();
2381 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002382 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002383 vc_conn.done;
2384
2385 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2386 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002387 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002388}
2389
Alexander Couzensf9858652018-06-07 16:14:53 +02002390private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2391 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002392 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002393
2394 /* unregister the old IMSI */
2395 f_bssgp_client_unregister(g_pars.imsi);
2396 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002397 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002398 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002399
2400 /* there is no auth */
2401 g_pars.net.expect_auth := false;
2402
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002403 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002404 f_gmm_auth();
2405 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002406 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002407 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002408 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002409 }
Harald Welte955aa942019-05-03 01:29:29 +02002410 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2411 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002412 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002413 setverdict(pass);
2414 }
2415 }
2416}
Alexander Couzens03d12242018-08-07 16:13:52 +02002417
2418private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2419
2420 f_TC_attach_closed_foreign(id);
2421 f_TC_attach_closed_imsi_added(id);
2422
2423}
2424
2425
Alexander Couzensf9858652018-06-07 16:14:53 +02002426testcase TC_attach_closed_add_vty() runs on test_CT {
2427 /* VTY-> SGSN: policy close
2428 * MS -> SGSN: Attach Request
2429 * MS <- SGSN: Identity Request IMSI
2430 * MS -> SGSN: Identity Response IMSI
2431 * MS <- SGSN: Attach Reject
2432 * VTY-> SGSN: policy imsi-acl add IMSI
2433 * MS -> SGSN: Attach Request
2434 * MS <- SGSN: Identity Request IMSI
2435 * MS -> SGSN: Identity Response IMSI
2436 * MS <- SGSN: Identity Request IMEI
2437 * MS -> SGSN: Identity Response IMEI
2438 * MS <- SGSN: Attach Accept
2439 */
2440 var BSSGP_ConnHdlr vc_conn;
2441 f_init();
2442 f_sleep(1.0);
2443 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2444 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002445 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2446 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002447 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002448 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002449 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002450 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002451}
2452
Alexander Couzens0085bd72018-06-12 19:08:44 +02002453/* Attempt an attach, but never answer a Attach Complete */
2454private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2455 var integer count_req := 0;
2456
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002457 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 +02002458 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002459 /* Expect SGSN to perform LU with HLR */
2460 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002461
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002462 timer T := 10.0;
2463 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002464 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002465 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002466 /* break */
2467 }
Harald Welte955aa942019-05-03 01:29:29 +02002468 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469 /* ignore */
2470 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002471 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002472 repeat;
2473 }
2474 }
2475 if (count_req != 5) {
2476 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002477 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002478 }
2479 setverdict(pass);
2480}
2481
2482testcase TC_attach_check_complete_resend() runs on test_CT {
2483 /* MS -> SGSN: Attach Request IMSI
2484 * MS <- SGSN: Identity Request *
2485 * MS -> SGSN: Identity Response *
2486 * MS <- SGSN: Attach Complete 5x
2487 */
2488 var BSSGP_ConnHdlr vc_conn;
2489 f_init();
2490 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002491 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 +02002492 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002493 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002494}
2495
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002496friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002497 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002498 var PDU_DTAP_PS_MT mt;
2499 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002500
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002501 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002502 p_tmsi := g_pars.p_tmsi;
2503 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002504 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002505 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 +02002506 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002507 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2508 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2509 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002510 setverdict(pass);
2511 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002512 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2513 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2514 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002515 setverdict(pass);
2516 }
2517
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002518 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002519 setverdict(fail, "Unexpected RAU Reject");
2520 mtc.stop;
2521 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002522 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002523 setverdict(fail, "Unexpected RAU Reject");
2524 mtc.stop;
2525 }
2526
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002527 [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 +02002528 key_sts := ?)) {
2529 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2530 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002531 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002532 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002533 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002534 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2535 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002536 }
2537}
2538
Alexander Couzensbfda9212018-07-31 03:17:33 +02002539private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002540 /* first perform regular attach */
2541 f_TC_attach(id);
2542
2543 /* then send RAU */
2544 f_routing_area_update(g_pars.ra);
2545
2546 /* do another RAU */
2547 f_routing_area_update(g_pars.ra);
2548
2549 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2550}
2551
2552testcase TC_attach_rau_a_a() runs on test_CT {
2553 /* MS <-> SGSN: Successful Attach
2554 * MS -> SGSN: Routing Area Update Request
2555 * MS <- SGSN: Routing Area Update Accept
2556 * MS -> SGSN: Routing Area Update Request
2557 * MS <- SGSN: Routing Area Update Accept
2558 * MS -> SGSN: Detach (PowerOff)
2559 */
2560 var BSSGP_ConnHdlr vc_conn;
2561 f_init();
2562 f_sleep(1.0);
2563 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2564 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002565 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002566}
2567
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002568private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002569 f_TC_attach(id);
2570
2571 log("attach complete sending rau");
2572 f_routing_area_update(g_pars.ra, 0);
2573
2574 log("rau complete unregistering");
2575 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002576 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002577
2578 log("sending second RAU via different RA");
2579 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2580
2581 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2582}
2583
2584testcase TC_attach_rau_a_b() runs on test_CT {
2585 /* MS <-> SGSN: Successful Attach
2586 * MS -> SGSN: Routing Area _a_ Update Request
2587 * MS <- SGSN: Routing Area _a_ Update Accept
2588 * MS -> SGSN: Routing Area _b_ Update Request
2589 * MS <- SGSN: Routing Area _b_ Update Accept
2590 * MS -> SGSN: Detach (PowerOff)
2591 */
2592 var BSSGP_ConnHdlr vc_conn;
2593 f_init();
2594 f_sleep(1.0);
2595 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2596 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002597 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002598}
2599
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002600private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2601 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002602 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002603 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002604 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002605
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002606 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002607
2608 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002609 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002610 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2611 mtc.stop;
2612 }
Harald Welte955aa942019-05-03 01:29:29 +02002613 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002614 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002615 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002616 repeat;
2617 }
Harald Welte955aa942019-05-03 01:29:29 +02002618 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002619 /* send out a second GMM_Attach Request.
2620 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2621 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002622 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002623 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002624 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002625 }
2626 }
2627 f_sleep(1.0);
2628
2629 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2630 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002631 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002632 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002633 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002634 repeat;
2635 }
Harald Welte955aa942019-05-03 01:29:29 +02002636 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002637 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2638 mtc.stop;
2639 }
Harald Welte955aa942019-05-03 01:29:29 +02002640 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002641 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2642 mtc.stop;
2643 }
Harald Welte955aa942019-05-03 01:29:29 +02002644 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2645 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002646 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002647 setverdict(pass);
2648 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2649 }
2650 }
2651}
2652
2653testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2654 /* Testing if the SGSN ignore Attach Request with the exact same content */
2655 /* MS -> SGSN: Attach Request IMSI
2656 * MS <- SGSN: Identity Request IMSI (optional)
2657 * MS -> SGSN: Identity Response IMSI (optional)
2658 * MS <- SGSN: Identity Request IMEI
2659 * MS -> SGSN: Attach Request (2nd)
2660 * MS <- SGSN: Identity Response IMEI
2661 * MS <- SGSN: Attach Accept
2662 * MS -> SGSN: Attach Complete
2663 */
2664 var BSSGP_ConnHdlr vc_conn;
2665 f_init();
2666 f_sleep(1.0);
2667 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2668 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2669 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002670 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002671}
2672
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002673private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002674 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2675
2676 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2677
2678 /* send Attach Request */
2679 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2680 * 3G auth vectors */
2681 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2682 /* The thing is, if the solSACapability is 'omit', then the
2683 * revisionLevelIndicatior is at the wrong place! */
2684 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002685 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002686
2687 /* do the auth */
2688 var PDU_L3_MS_SGSN l3_mo;
2689 var PDU_L3_SGSN_MS l3_mt;
2690 var default di := activate(as_mm_identity());
2691
2692 var GSUP_IE auth_tuple;
2693 var template AuthenticationParameterAUTNTLV autn;
2694
2695 g_pars.vec := f_gen_auth_vec_3g();
2696 autn := {
2697 elementIdentifier := '28'O,
2698 lengthIndicator := lengthof(g_pars.vec.autn),
2699 autnValue := g_pars.vec.autn
2700 };
2701 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2702 g_pars.vec.sres,
2703 g_pars.vec.kc,
2704 g_pars.vec.ik,
2705 g_pars.vec.ck,
2706 g_pars.vec.autn,
2707 g_pars.vec.res));
2708 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2709 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2710 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2711
2712 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2713 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002714 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002715
2716 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002717 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002718
2719 /* wait for the GSUP resync request */
2720 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2721 g_pars.imsi,
2722 g_pars.vec.auts,
2723 g_pars.vec.rand));
2724
2725 /* generate new key material */
2726 g_pars.vec := f_gen_auth_vec_3g();
2727 autn := {
2728 elementIdentifier := '28'O,
2729 lengthIndicator := lengthof(g_pars.vec.autn),
2730 autnValue := g_pars.vec.autn
2731 };
2732
2733 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2734 g_pars.vec.sres,
2735 g_pars.vec.kc,
2736 g_pars.vec.ik,
2737 g_pars.vec.ck,
2738 g_pars.vec.autn,
2739 g_pars.vec.res));
2740 /* send new key material */
2741 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2742
2743 /* wait for the new Auth Request */
2744 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2745 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002746 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002747 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2748 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2749 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2750 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2751 valueField := substr(g_pars.vec.res, 0, 4)
2752 };
2753 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2754 elementIdentifier := '21'O,
2755 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2756 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2757 };
2758 l3_mo := valueof(auth_ciph_resp);
2759 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2760 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2761 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2762 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2763 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002764 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002765 deactivate(di);
2766
2767 /* Expect SGSN to perform LU with HLR */
2768 f_gmm_gsup_lu_isd();
2769
Harald Welte955aa942019-05-03 01:29:29 +02002770 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2771 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002772 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002773 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002774 setverdict(pass);
2775}
2776
2777testcase TC_attach_usim_resync() runs on test_CT {
2778 /* MS -> SGSN: Attach Request
2779 * MS <- SGSN: Identity Request IMSI
2780 * MS -> SGSN: Identity Response IMSI
2781 * MS <- SGSN: Identity Request IMEI
2782 * MS -> SGSN: Identity Response IMEI
2783 * HLR<- SGSN: SAI Request
2784 * HLR-> SGSN: SAI Response
2785 * MS <- SGSN: Auth Request
2786 * MS -> SGSN: Auth Failure (with AUTS)
2787 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2788 * HLR-> SGSN: SAI Response (new key material)
2789 * MS <- SGSN: Auth Request (new key material)
2790 * MS -> SGSN: Auth Response
2791 * MS <- SGSN: Attach Accept
2792 * MS -> SGSN: Attach Complete
2793 */
2794 var BSSGP_ConnHdlr vc_conn;
2795 f_init();
2796 f_sleep(1.0);
2797 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2798 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002799 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002800}
2801
Harald Weltea05b8072019-04-23 22:35:05 +02002802
2803/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2804private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2805 f_gmm_attach(false, false);
2806 f_sleep(1.0);
2807 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2808 /* try to detach to check if SGSN is still alive */
2809 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2810}
2811testcase TC_llc_null() runs on test_CT {
2812 var BSSGP_ConnHdlr vc_conn;
2813 f_init();
2814 f_sleep(1.0);
2815 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2816 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002817 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002818}
2819
Harald Welte645a1512019-04-23 23:18:23 +02002820/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2821private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2822 f_gmm_attach(false, false);
2823 f_sleep(1.0);
2824 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002825 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002826 setverdict(pass);
2827}
2828testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2829 var BSSGP_ConnHdlr vc_conn;
2830 f_init();
2831 f_sleep(1.0);
2832 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2833 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002834 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002835}
2836
2837/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2838private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2839 f_gmm_attach(false, false);
2840 f_sleep(1.0);
2841 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002842 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002843 setverdict(pass);
2844}
2845testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2846 var BSSGP_ConnHdlr vc_conn;
2847 f_init();
2848 f_sleep(1.0);
2849 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2850 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002851 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002852}
2853
Harald Welte2aaac1b2019-05-02 10:02:53 +02002854/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2855private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2856 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2857 var template (value) XID_Information xid;
2858 var template XID_Information xid_rx;
2859
2860 /* first perform regular attach */
2861 f_TC_attach(id);
2862 /* then activate PDP context */
2863 f_pdp_ctx_act(apars);
2864
2865 /* start MO XID */
2866 xid := { ts_XID_L3(''O) };
2867 xid_rx := { tr_XID_L3(''O) };
2868 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2869 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002870 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002871 [] as_xid(apars);
2872 }
2873 setverdict(pass);
2874}
2875testcase TC_xid_empty_l3() runs on test_CT {
2876 var BSSGP_ConnHdlr vc_conn;
2877 f_init();
2878 f_sleep(1.0);
2879 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2880 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002881 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002882}
2883
2884private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2885 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2886 var template (value) XID_Information xid;
2887 var template XID_Information xid_rx;
2888
2889 /* first perform regular attach */
2890 f_TC_attach(id);
2891 /* then activate PDP context */
2892 f_pdp_ctx_act(apars);
2893
2894 /* start MO XID */
2895 xid := { ts_XID_N201U(1234) };
2896 xid_rx := { tr_XID_N201U(1234) };
2897 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2898 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002899 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002900 [] as_xid(apars);
2901 }
2902 setverdict(pass);
2903}
2904testcase TC_xid_n201u() runs on test_CT {
2905 var BSSGP_ConnHdlr vc_conn;
2906 f_init();
2907 f_sleep(1.0);
2908 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2909 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002910 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002911}
2912
Alexander Couzens6bee0872019-05-11 01:48:50 +02002913private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2914 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2915
2916 /* first perform regular attach */
2917 f_TC_attach(id);
2918 /* then activate PDP context */
2919 f_pdp_ctx_act(apars);
2920 /* do a normal detach */
2921 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2922}
2923
2924testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2925 /* MS -> SGSN: Attach Request
2926 * MS <-> SGSN: [..]
2927 * MS -> SGSN: Attach Complete
2928 * MS -> SGSN: PDP Activate Request
2929 * MS <- SGSN: PDP Activate Accept
2930 * MS -> SGSN: GMM Detach Request
2931 * MS <- SGSN: GMM Detach Accept
2932 */
2933 var BSSGP_ConnHdlr vc_conn;
2934 f_init();
2935 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2936 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002937 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002938}
Harald Welte645a1512019-04-23 23:18:23 +02002939
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002940private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2941 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2942 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2943 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2944 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2945 var PDU_L3_SGSN_MS l3_mt;
2946
2947 f_send_l3(attach_req, 0);
2948
2949 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2950
2951 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2952 alt {
2953 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2954 setverdict(pass);
2955 }
2956 [] BSSGP[0].receive { repeat; }
2957 }
2958}
2959
2960/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2961 * See OS#3957 and OS#4245 for more information.
2962 */
2963testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2964 /*
2965 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2966 * MS <-- SGSN: Identity Request (IMEI)
2967 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2968 */
2969 var BSSGP_ConnHdlr vc_conn;
2970 f_init();
2971 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2972 vc_conn.done;
2973 f_cleanup();
2974}
2975
Harald Welte8e5932e2020-06-17 22:12:54 +02002976private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2977var PDU_BSSGP rx;
2978[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2979 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2980 mtc.stop;
2981 }
2982}
2983
2984/* SUSPEND, then DL traffic: should not pass + no paging expected */
2985private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2986 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2987 var default d;
2988
2989 /* first perform regular attach */
2990 f_TC_attach(id);
2991 /* then activate PDP context */
2992 f_pdp_ctx_act(apars);
2993 /* then transceive a downlink PDU */
2994 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2995
2996 /* now suspend GPRS */
2997 f_bssgp_suspend();
2998
2999 d := activate(as_nopaging_ps());
3000
3001 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3002 * nor any related paging requests */
3003 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3004
3005 deactivate(d);
3006}
3007testcase TC_suspend_nopaging() runs on test_CT {
3008 var BSSGP_ConnHdlr vc_conn;
3009 f_init();
3010 f_sleep(1.0);
3011 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3012 vc_conn.done;
3013 f_cleanup();
3014}
3015
3016
3017/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3018private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3019 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3020 var OCT1 susp_ref;
3021 var default d;
3022
3023 /* first perform regular attach */
3024 f_TC_attach(id);
3025 /* then activate PDP context */
3026 f_pdp_ctx_act(apars);
3027 /* then transceive a downlink PDU */
3028 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3029
3030 /* now suspend GPRS */
3031 susp_ref := f_bssgp_suspend();
3032
3033 d := activate(as_nopaging_ps());
3034
3035 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3036 * nor any related paging requests */
3037 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3038
3039 deactivate(d);
3040
3041 /* resume GPRS */
3042 f_bssgp_resume(susp_ref);
3043
3044 /* now data should be flowing again */
3045 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3046}
3047testcase TC_suspend_resume() runs on test_CT {
3048 var BSSGP_ConnHdlr vc_conn;
3049 f_init();
3050 f_sleep(1.0);
3051 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3052 vc_conn.done;
3053 f_cleanup();
3054}
3055
3056/* SUSPEND, then RAU: data expected to flow after implicit resume */
3057private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3058 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3059 var default d;
3060
3061 /* first perform regular attach */
3062 f_TC_attach(id);
3063 /* then activate PDP context */
3064 f_pdp_ctx_act(apars);
3065 /* then transceive a downlink PDU */
3066 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3067
3068 /* now suspend GPRS */
3069 f_bssgp_suspend();
3070
3071 d := activate(as_nopaging_ps());
3072
3073 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3074 * nor any related paging requests */
3075 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3076
3077 deactivate(d);
3078
3079 /* perform RAU (implicit RESUME) */
3080 f_routing_area_update(g_pars.ra);
3081
3082 /* now data should be flowing again */
3083 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3084
3085}
3086testcase TC_suspend_rau() runs on test_CT {
3087 var BSSGP_ConnHdlr vc_conn;
3088 f_init();
3089 f_sleep(1.0);
3090 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3091 vc_conn.done;
3092 f_cleanup();
3093}
3094
3095
3096/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3097private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3098 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3099 var default d;
3100
3101 /* first perform regular attach */
3102 f_TC_attach(id);
3103 /* then activate PDP context */
3104 f_pdp_ctx_act(apars);
3105 /* then transceive a downlink PDU */
3106 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3107
3108 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3109 f_sleep(5.0);
3110
3111 /* now data should be flowing again, but with PS PAGING */
3112 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3113 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3114
3115 /* FIXME: simulate paging response */
3116 /* FIXME: verify PDU actually arrives only after paging response was successful */
3117
3118}
3119testcase TC_paging_ps() runs on test_CT {
3120 var BSSGP_ConnHdlr vc_conn;
3121 f_init();
3122 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3123 f_sleep(1.0);
3124 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3125 vc_conn.done;
3126 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3127 f_cleanup();
3128}
3129
3130
3131
3132
3133
Harald Welte5ac31492018-02-15 20:39:13 +01003134control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003135 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003136 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003137 execute( TC_attach_umts_aka_umts_res() );
3138 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003139 execute( TC_attach_auth_id_timeout() );
3140 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003141 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003142 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003143 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003144 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003145 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003146 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003147 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003148 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003149 execute( TC_attach_closed_add_vty(), 20.0 );
3150 execute( TC_attach_check_subscriber_list(), 20.0 );
3151 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003152 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003153 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3154 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3155 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3156 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003157 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003158 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003159 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003160 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003161 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003162 execute( TC_detach_unknown_nopoweroff() );
3163 execute( TC_detach_unknown_poweroff() );
3164 execute( TC_detach_nopoweroff() );
3165 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003166 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003167 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003168 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003169 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003170 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003171 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003172 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003173 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003174 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003175 execute( TC_attach_restart_ctr_echo() );
3176 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003177 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003178 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3179 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003180 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003181 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003182 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003183
Harald Welte2aaac1b2019-05-02 10:02:53 +02003184 execute( TC_xid_empty_l3() );
3185 execute( TC_xid_n201u() );
3186
Harald Weltea05b8072019-04-23 22:35:05 +02003187 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003188 execute( TC_llc_sabm_dm_llgmm() );
3189 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003190
Harald Welte8e5932e2020-06-17 22:12:54 +02003191 execute( TC_suspend_nopaging() );
3192 execute( TC_suspend_resume() );
3193 execute( TC_suspend_rau() );
3194 execute( TC_paging_ps() );
3195
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003196 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3197 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003198}
Harald Welte96a33b02018-02-04 10:36:22 +01003199
3200
3201
3202}