blob: 53ecdff391ac59bf2e442bafdcf633b5f255c7be [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 Welte5e8573e2020-09-13 15:32:56 +020072 provider := {
73 ip := {
74 address_family := AF_INET,
75 local_udp_port := 21010,
76 local_ip := "127.0.0.1",
77 remote_udp_port := 23000,
78 remote_ip := "127.0.0.1"
79 }
80 },
Alexander Couzensf3c1b412018-08-24 00:42:51 +020081 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020082 nsei := 96,
83 role_sgsn := false,
84 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020085 },
86 {
Harald Welte5e8573e2020-09-13 15:32:56 +020087 provider := {
88 ip := {
89 address_family := AF_INET,
90 local_udp_port := 21011,
91 local_ip := "127.0.0.1",
92 remote_udp_port := 23000,
93 remote_ip := "127.0.0.1"
94 }
95 },
Alexander Couzensf3c1b412018-08-24 00:42:51 +020096 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020097 nsei := 97,
98 role_sgsn := false,
99 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200100 },
101 {
Harald Welte5e8573e2020-09-13 15:32:56 +0200102 provider := {
103 ip := {
104 address_family := AF_INET,
105 local_udp_port := 21012,
106 local_ip := "127.0.0.1",
107 remote_udp_port := 23000,
108 remote_ip := "127.0.0.1"
109 }
110 },
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200111 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +0200112 nsei := 98,
113 role_sgsn := false,
114 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200115 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200116 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200117
118 RAN_Configurations mp_ranap_cfg := {
119 {
120 transport := RANAP_TRANSPORT_IuCS,
121 sccp_service_type := "mtp3_itu",
122 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
123 own_pc := 195,
124 own_ssn := 142,
125 peer_pc := 188, /* 0.23.4 */
126 peer_ssn := 142,
127 sio := '83'O,
128 rctx := 2
129 }
130 }
Harald Welte5ac31492018-02-15 20:39:13 +0100131};
132
Harald Welte5339b2e2020-10-04 22:52:56 +0200133const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100134type record GbInstance {
135 NS_CT vc_NS,
136 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200137 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100138 BssgpConfig cfg
139};
Harald Welte96a33b02018-02-04 10:36:22 +0100140
Harald Welte2fa771f2019-05-02 20:13:53 +0200141const integer NUM_GB := 3;
142type record length(NUM_GB) of GbInstance GbInstances;
143type record length(NUM_GB) of NSConfiguration NSConfigurations;
144type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200145
Harald Welte26fbb6e2019-04-14 17:32:46 +0200146const integer NUM_RNC := 1;
147type record of RAN_Configuration RAN_Configurations;
148
Harald Welte96a33b02018-02-04 10:36:22 +0100149type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200150 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200151 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200152 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100153
Harald Welte5ac31492018-02-15 20:39:13 +0100154 var GSUP_Emulation_CT vc_GSUP;
155 var IPA_Emulation_CT vc_GSUP_IPA;
156 /* only to get events from IPA underneath GSUP */
157 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100158
Harald Welte5339b2e2020-10-04 22:52:56 +0200159 /* only needed at start to get the per-BVC references */
160 port BSSGP_CT_PROC_PT PROC;
161
Harald Welteeded9ad2018-02-17 20:57:34 +0100162 var GTP_Emulation_CT vc_GTP;
163
Harald Weltebd194722018-02-16 22:11:08 +0100164 port TELNETasp_PT SGSNVTY;
165
Harald Welte96a33b02018-02-04 10:36:22 +0100166 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200167 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100168};
169
Harald Welte26fbb6e2019-04-14 17:32:46 +0200170type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100171 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100172 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200173 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100174}
175
176type record SGSN_ConnHdlrNetworkPars {
177 boolean expect_ptmsi,
178 boolean expect_auth,
179 boolean expect_ciph
180};
181
182type record BSSGP_ConnHdlrPars {
183 /* IMEI of the simulated ME */
184 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200185 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100186 hexstring imsi,
187 /* MSISDN of the simulated MS (probably unused) */
188 hexstring msisdn,
189 /* P-TMSI allocated to the simulated MS */
190 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100191 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100192 /* TLLI of the simulated MS */
193 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100194 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100195 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200196 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200197 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
198 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100199 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100200 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200201 float t_guard,
202 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200203 SCCP_PAR_Address sccp_addr_local optional,
204 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100205};
206
Alexander Couzens89508702018-07-31 04:16:10 +0200207private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200208 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200209 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
210
211 var RoutingAreaIdentificationV ret := {
212 mccDigit1 := mcc_mnc[0],
213 mccDigit2 := mcc_mnc[1],
214 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200215 mncDigit3 := mcc_mnc[3],
216 mncDigit1 := mcc_mnc[4],
217 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200218 lac := int2oct(cell_id.ra_id.lai.lac, 16),
219 rac := int2oct(cell_id.ra_id.rac, 8)
220 }
221 return ret;
222};
223
Alexander Couzens51114d12018-07-31 18:41:56 +0200224private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
225 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
226 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100227 /* connect lower end of BSSGP emulation with NS upper port */
228 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100229
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200230 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200231 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
232 /* resolve the per-BVC component references */
233 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
234 connect(self:PROC, gb.vc_BSSGP:PROC);
235 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
236 disconnect(self:PROC, gb.vc_BSSGP:PROC);
237 }
Harald Welte5ac31492018-02-15 20:39:13 +0100238}
239
240private function f_init_gsup(charstring id) runs on test_CT {
241 id := id & "-GSUP";
242 var GsupOps ops := {
243 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
244 };
245
246 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
247 vc_GSUP := GSUP_Emulation_CT.create(id);
248
249 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
250 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
251 /* we use this hack to get events like ASP_IPA_EVENT_UP */
252 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
253
254 vc_GSUP.start(GSUP_Emulation.main(ops, id));
255 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
256
257 /* wait for incoming connection to GSUP port before proceeding */
258 timer T := 10.0;
259 T.start;
260 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700261 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100262 [] T.timeout {
263 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200264 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100265 }
266 }
267}
268
Harald Welteeded9ad2018-02-17 20:57:34 +0100269private function f_init_gtp(charstring id) runs on test_CT {
270 id := id & "-GTP";
271
272 var GtpEmulationCfg gtp_cfg := {
273 gtpc_bind_ip := mp_ggsn_ip,
274 gtpc_bind_port := GTP1C_PORT,
275 gtpu_bind_ip := mp_ggsn_ip,
276 gtpu_bind_port := GTP1U_PORT,
277 sgsn_role := false
278 };
279
280 vc_GTP := GTP_Emulation_CT.create(id);
281 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
282}
283
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200284friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100285 map(self:SGSNVTY, system:SGSNVTY);
286 f_vty_set_prompts(SGSNVTY);
287 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200288 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100289 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
290}
291
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200292private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
293 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200294 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200295 } else {
296 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
297 }
298}
299
Harald Weltebd194722018-02-16 22:11:08 +0100300
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200301/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
302function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200303 var integer i;
304
Harald Welte96a33b02018-02-04 10:36:22 +0100305 if (g_initialized == true) {
306 return;
307 }
308 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100309 g_gb[0].cfg := {
310 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200311 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200312 bvc := {
313 {
314 bvci := 196,
315 cell_id := {
316 ra_id := {
317 lai := {
318 mcc_mnc := mcc_mnc,
319 lac := 13135
320 },
321 rac := 0
322 },
323 cell_id := 20960
324 },
325 depth := BSSGP_DECODE_DEPTH_L3
326 }
327 }
Harald Welte5ac31492018-02-15 20:39:13 +0100328 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200329 g_gb[1].cfg := {
330 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200331 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200332 bvc := {
333 {
334 bvci := 210,
335 cell_id := {
336 ra_id := {
337 lai := {
338 mcc_mnc := mcc_mnc,
339 lac := 13200
340 },
341 rac := 0
342 },
343 cell_id := 20961
344 },
345 depth := BSSGP_DECODE_DEPTH_L3
346 }
347 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200348 };
349 g_gb[2].cfg := {
350 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200351 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200352 bvc := {
353 {
354 bvci := 220,
355 cell_id := {
356 ra_id := {
357 lai := {
358 mcc_mnc := mcc_mnc,
359 lac := 13300
360 },
361 rac := 0
362 },
363 cell_id := 20962
364 },
365 depth := BSSGP_DECODE_DEPTH_L3
366 }
367 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200368 };
Harald Welte96a33b02018-02-04 10:36:22 +0100369
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200370 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200371 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
372 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
373 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200374
Alexander Couzens1552e792019-07-23 20:38:39 +0200375 if (g_ranap_enable) {
376 for (i := 0; i < NUM_RNC; i := i+1) {
377 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
378 f_ran_adapter_start(g_ranap[i]);
379 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200380 }
Harald Welte5ac31492018-02-15 20:39:13 +0100381 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100382 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200383 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100384}
Harald Welte96a33b02018-02-04 10:36:22 +0100385
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200386function f_cleanup() runs on test_CT {
387 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200388 if (g_ranap_enable) {
389 for (i := 0; i < NUM_RNC; i := i+1) {
390 f_ran_adapter_cleanup(g_ranap[i]);
391 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200392 }
393 self.stop;
394}
395
Harald Welte26fbb6e2019-04-14 17:32:46 +0200396private function RncUnitdataCallback(RANAP_PDU ranap)
397runs on RAN_Emulation_CT return template RANAP_PDU {
398 var template RANAP_PDU resp := omit;
399
400 log ("RANAP_RncUnitDataCallback");
401 /* answer all RESET with RESET ACK */
402 if (match(ranap, tr_RANAP_Reset)) {
403 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
404 var CN_DomainIndicator dom;
405 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
406 resp := ts_RANAP_ResetAck(dom);
407 }
408 return resp;
409}
410
411const RanOps RNC_RanOps := {
412 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
413 ranap_unitdata_cb := refers(RncUnitdataCallback),
414 ps_domain := true,
415 decode_dtap := true,
416 role_ms := true,
417 protocol := RAN_PROTOCOL_RANAP,
418 transport := RANAP_TRANSPORT_IuCS,
419 use_osmux := false,
420 sccp_addr_local := omit,
421 sccp_addr_peer := omit
422};
423
Harald Welte5ac31492018-02-15 20:39:13 +0100424type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
425
426/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200427function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100428 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100429runs on test_CT return BSSGP_ConnHdlr {
430 var BSSGP_ConnHdlr vc_conn;
431 var SGSN_ConnHdlrNetworkPars net_pars := {
432 expect_ptmsi := true,
433 expect_auth := true,
434 expect_ciph := false
435 };
436 var BSSGP_ConnHdlrPars pars := {
437 imei := f_gen_imei(imsi_suffix),
438 imsi := f_gen_imsi(imsi_suffix),
439 msisdn := f_gen_msisdn(imsi_suffix),
440 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100441 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100442 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100443 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100444 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200445 bssgp_cell_id := {
446 gb[0].cfg.bvc[0].cell_id,
447 gb[1].cfg.bvc[0].cell_id,
448 gb[2].cfg.bvc[0].cell_id
449 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200450 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100451 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100452 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200453 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200454 sccp_addr_local := omit,
455 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100456 };
457
Alexander Couzens1552e792019-07-23 20:38:39 +0200458 if (g_ranap_enable) {
459 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
460 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
461 }
462
Harald Welte5ac31492018-02-15 20:39:13 +0100463 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200464
465 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
466 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
467 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
468
469 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
470 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
471 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
472
473 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
474 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
475 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100476
Harald Welte26fbb6e2019-04-14 17:32:46 +0200477 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200478 if (g_ranap_enable) {
479 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
480 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
481 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200482
Harald Welte5ac31492018-02-15 20:39:13 +0100483 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
484 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
485
Harald Welteeded9ad2018-02-17 20:57:34 +0100486 connect(vc_conn:GTP, vc_GTP:CLIENT);
487 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
488
Harald Welte5ac31492018-02-15 20:39:13 +0100489 vc_conn.start(f_handler_init(fn, id, pars));
490 return vc_conn;
491}
492
Harald Welte62e29582018-02-16 21:17:11 +0100493private altstep as_Tguard() runs on BSSGP_ConnHdlr {
494 [] g_Tguard.timeout {
495 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200496 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100497 }
498}
499
Harald Welte5ac31492018-02-15 20:39:13 +0100500/* first function called in every ConnHdlr */
501private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
502runs on BSSGP_ConnHdlr {
503 /* do some common stuff like setting up g_pars */
504 g_pars := pars;
505
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200506 llc := f_llc_create(false);
507
Harald Welte5ac31492018-02-15 20:39:13 +0100508 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200509 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100510 /* tell GSUP dispatcher to send this IMSI to us */
511 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100512 /* tell GTP dispatcher to send this IMSI to us */
513 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100514
Harald Welte62e29582018-02-16 21:17:11 +0100515 g_Tguard.start(pars.t_guard);
516 activate(as_Tguard());
517
Harald Welte5ac31492018-02-15 20:39:13 +0100518 /* call the user-supplied test case function */
519 fn.apply(id);
520 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100521}
522
523/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100524 * Detach without Attach
525 * SM procedures without attach / RAU
526 * ATTACH / RAU
527 ** with / without authentication
528 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100529 * re-transmissions of LLC frames
530 * PDP Context activation
531 ** with different GGSN config in SGSN VTY
532 ** with different PDP context type (v4/v6/v46)
533 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100534 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100535 */
536
537testcase TC_wait_ns_up() runs on test_CT {
538 f_init();
539 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200540 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100541}
542
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200543friend function is_gb(integer ran_index) return boolean {
544 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200545}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200546friend function is_iu(integer ran_index) return boolean {
547 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200548}
549
Alexander Couzens0507ec32019-09-15 22:41:22 +0200550function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200551 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200552 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 +0200553}
554
Alexander Couzens0507ec32019-09-15 22:41:22 +0200555private 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 +0200556 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
557 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
558 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200559 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200560}
561
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200562/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
563function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
564 log("Sending InitialUE: ", l3_mo);
565 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
566 var RANAP_PDU ranap;
567 var LAI lai := {
568 pLMNidentity := '62F224'O,
569 lAC := '1234'O,
570 iE_Extensions := omit
571 };
572 var SAI sai := {
573 pLMNidentity := lai.pLMNidentity,
574 lAC := lai.lAC,
575 sAC := '0000'O, /* FIXME */
576 iE_Extensions := omit
577 };
578 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
579 var GlobalRNC_ID grnc_id := {
580 pLMNidentity := lai.pLMNidentity,
581 rNC_ID := 2342 /* FIXME */
582 };
583
584 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
585 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
586 alt {
587 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
588 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
589 setverdict(fail, "DISC.ind from SCCP");
590 mtc.stop;
591 }
592 }
593}
594
595/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200596function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
597 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200598 if (g_pars.rnc_send_initial_ue) {
599 g_pars.rnc_send_initial_ue := false;
600 f_send_l3_initial_ue(l3_mo);
601 } else {
602 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
603 }
604 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200605 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200606 }
607}
608
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200609altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700610 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200611 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100612 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200613 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100614 repeat;
615 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200616 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200617 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200618 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200619 repeat;
620 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200621 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100622 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200623 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200624 repeat;
625 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200626 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200627 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
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 }
631}
Harald Welte96a33b02018-02-04 10:36:22 +0100632
Harald Welteca362462019-05-02 20:11:21 +0200633/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200634function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200635runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200636 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200637 var PDU_L3_SGSN_MS l3_mt;
638 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200639 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
640 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200641 l3_mt := mt.dtap;
642 }
Harald Welteca362462019-05-02 20:11:21 +0200643 }
644 return l3_mt;
645}
646
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200647/* perform GMM authentication (if expected).
648 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
649 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200650function 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 +0100651 var PDU_L3_MS_SGSN l3_mo;
652 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200653 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100654 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200655 var GSUP_IE auth_tuple;
656 var template AuthenticationParameterAUTNTLV autn;
657
658 if (umts_aka_challenge) {
659 g_pars.vec := f_gen_auth_vec_3g();
660 autn := {
661 elementIdentifier := '28'O,
662 lengthIndicator := lengthof(g_pars.vec.autn),
663 autnValue := g_pars.vec.autn
664 };
665
666 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
667 g_pars.vec.sres,
668 g_pars.vec.kc,
669 g_pars.vec.ik,
670 g_pars.vec.ck,
671 g_pars.vec.autn,
672 g_pars.vec.res));
673 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
674 } else {
675 g_pars.vec := f_gen_auth_vec_2g();
676 autn := omit;
677 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
678 g_pars.vec.sres,
679 g_pars.vec.kc));
680 log("GSUP sends only 2G auth tuple", auth_tuple);
681 }
Harald Welteca362462019-05-02 20:11:21 +0200682
Harald Welte5ac31492018-02-15 20:39:13 +0100683 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
684 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200685
686 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
687 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200688 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100689 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200690 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
691
692 if (umts_aka_challenge and not force_gsm_sres) {
693 /* set UMTS response instead */
694 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
695 valueField := substr(g_pars.vec.res, 0, 4)
696 };
697 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
698 elementIdentifier := '21'O,
699 lengthIndicator := lengthof(g_pars.vec.res) - 4,
700 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
701 };
702 }
703
704 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100705 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
706 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
707 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
708 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
709 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200710 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200711
712 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200713 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200714 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
715 key_sts := ?)) {
716 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
717 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200718 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200719 }
720 }
Harald Welte76dee092018-02-16 22:12:59 +0100721 } else {
722 /* wait for identity procedure */
723 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100724 }
Harald Welte76dee092018-02-16 22:12:59 +0100725
Harald Welte5ac31492018-02-15 20:39:13 +0100726 deactivate(di);
727}
728
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200729function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100730 g_pars.p_tmsi := p_tmsi;
731 /* update TLLI */
732 g_pars.tlli_old := g_pars.tlli;
733 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100734 if (is_gb(ran_index)) {
735 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
736 }
Harald Weltef70997d2018-02-17 10:11:19 +0100737}
738
Harald Welte04683d02018-02-16 22:43:45 +0100739function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
740 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100741 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200742 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100743 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200744 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200745 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100746 }
Harald Welte04683d02018-02-16 22:43:45 +0100747 g_pars.ra := aa.routingAreaIdentification;
748 if (ispresent(aa.allocatedPTMSI)) {
749 if (not g_pars.net.expect_ptmsi) {
750 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200751 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100752 }
Harald Weltef70997d2018-02-17 10:11:19 +0100753 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100754 }
755 if (ispresent(aa.msIdentity)) {
756 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200757 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100758 }
759 /* P-TMSI.sig */
760 if (ispresent(aa.ptmsiSignature)) {
761 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
762 }
763 /* updateTimer */
764 // aa.readyTimer
765 /* T3302, T3319, T3323, T3312_ext, T3324 */
766}
767
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200768function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100769 /* mandatory IE */
770 g_pars.ra := ra.routingAreaId;
771 if (ispresent(ra.allocatedPTMSI)) {
772 if (not g_pars.net.expect_ptmsi) {
773 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200774 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100775 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200776 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100777 }
778 if (ispresent(ra.msIdentity)) {
779 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200780 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100781 }
782 /* P-TMSI.sig */
783 if (ispresent(ra.ptmsiSignature)) {
784 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
785 }
786 /* updateTimer */
787 // aa.readyTimer
788 /* T3302, T3319, T3323, T3312_ext, T3324 */
789}
790
791
Harald Welte5a4fa042018-02-16 20:59:21 +0100792function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
793 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
794}
795
Harald Welte23178c52018-02-17 09:36:33 +0100796/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700797private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100798 if (ispresent(g_pars.p_tmsi)) {
799 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
800 } else {
801 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
802 }
803}
804
Harald Welte311ec272018-02-17 09:40:03 +0100805private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100806 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100807 /* Expect MSC to perform LU with HLR */
808 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100809 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
810 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
811 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100812 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
813 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
814}
815
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200816friend 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 +0100817 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200818 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 +0200819 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100820
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200821 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
822 * 3G auth vectors */
823 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
824 /* The thing is, if the solSACapability is 'omit', then the
825 * revisionLevelIndicatior is at the wrong place! */
826 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
827
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200828 f_send_l3(attach_req, ran_index);
829 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200830 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100831 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100832
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200833 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200834 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
835
Harald Welte04683d02018-02-16 22:43:45 +0100836 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200837 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200838
839 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200840 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200841 as_iu_release_compl_disc();
842 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200843
844 /* Race condition
845 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
846 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
847 * arrived before it. This results in a test case failure.
848 * Delay execution by 50 ms
849 */
850 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200851}
852
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200853friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
854 timer T := 5.0;
855 var PDU_BSSGP rx_pdu;
856 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
857 T.start;
858 alt {
859 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
860 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
861 }
862 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
863 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
864 mtc.stop;
865 }
866 [] T.timeout {
867 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
868 mtc.stop;
869 }
870 }
871 return '00'O;
872}
873
874friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
875 timer T := 5.0;
876 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
877 T.start;
878 alt {
879 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
880 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
881?)) {
882 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
883 mtc.stop;
884 }
885 [] T.timeout {
886 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
887 mtc.stop;
888 }
889 }
890}
891
892
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200893private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
894 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100895 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100896}
897
898testcase TC_attach() runs on test_CT {
899 var BSSGP_ConnHdlr vc_conn;
900 f_init();
901 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200902 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100903 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200904 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100905}
906
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100907testcase TC_attach_mnc3() runs on test_CT {
908 var BSSGP_ConnHdlr vc_conn;
909 f_init('023042'H);
910 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200911 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100912 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200913 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100914}
915
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200916private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
917 f_gmm_attach(true, false);
918 setverdict(pass);
919}
920testcase TC_attach_umts_aka_umts_res() runs on test_CT {
921 var BSSGP_ConnHdlr vc_conn;
922 f_init();
923 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200924 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200925 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200926 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200927}
928
929private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
930 f_gmm_attach(true, true);
931 setverdict(pass);
932}
933testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
934 var BSSGP_ConnHdlr vc_conn;
935 f_init();
936 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200937 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200938 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200939 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200940}
941
Harald Welte5b7c8122018-02-16 21:48:17 +0100942/* MS never responds to ID REQ, expect ATTACH REJECT */
943private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100944 var RoutingAreaIdentificationV old_ra := f_random_RAI();
945
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200946 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100947 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200948 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100949 /* don't send ID Response */
950 repeat;
951 }
Harald Welte955aa942019-05-03 01:29:29 +0200952 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100953 setverdict(pass);
954 }
Harald Welte955aa942019-05-03 01:29:29 +0200955 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100956 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200957 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100958 }
959 }
960}
961testcase TC_attach_auth_id_timeout() runs on test_CT {
962 var BSSGP_ConnHdlr vc_conn;
963 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200964 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 +0100965 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200966 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100967}
968
969/* HLR never responds to SAI REQ, expect ATTACH REJECT */
970private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100971 var RoutingAreaIdentificationV old_ra := f_random_RAI();
972
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200973 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100974 alt {
975 [] as_mm_identity();
976 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
977 }
978 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200979 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100980 setverdict(pass);
981}
982testcase TC_attach_auth_sai_timeout() runs on test_CT {
983 var BSSGP_ConnHdlr vc_conn;
984 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200985 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100986 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200987 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100988}
989
Harald Weltefe253882018-02-17 09:25:00 +0100990/* HLR rejects SAI, expect ATTACH REJECT */
991private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100992 var RoutingAreaIdentificationV old_ra := f_random_RAI();
993
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200994 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100995 alt {
996 [] as_mm_identity();
997 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
998 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
999 }
1000 }
Harald Welte955aa942019-05-03 01:29:29 +02001001 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001002 setverdict(pass);
1003}
1004testcase TC_attach_auth_sai_reject() runs on test_CT {
1005 var BSSGP_ConnHdlr vc_conn;
1006 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001007 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001008 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001009 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001010}
1011
Harald Welte5b7c8122018-02-16 21:48:17 +01001012/* HLR never responds to UL REQ, expect ATTACH REJECT */
1013private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001014 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001015 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1016
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001017 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001018 f_gmm_auth();
1019 /* Expect MSC to perform LU with HLR */
1020 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1021 /* Never follow-up with ISD_REQ or UL_RES */
1022 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001023 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001024 setverdict(pass);
1025 }
Harald Welte955aa942019-05-03 01:29:29 +02001026 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1027 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001028 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001029 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001030 }
1031 }
1032}
1033testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1034 var BSSGP_ConnHdlr vc_conn;
1035 f_init();
1036 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001037 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001038 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001039 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001040}
1041
Harald Welteb7c14e92018-02-17 09:29:16 +01001042/* HLR rejects UL REQ, expect ATTACH REJECT */
1043private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001044 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001045 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1046
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001047 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001048 f_gmm_auth();
1049 /* Expect MSC to perform LU with HLR */
1050 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1051 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1052 }
1053 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001054 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001055 setverdict(pass);
1056 }
Harald Welte955aa942019-05-03 01:29:29 +02001057 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1058 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001059 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001060 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001061 }
1062 }
1063}
1064testcase TC_attach_gsup_lu_reject() runs on test_CT {
1065 var BSSGP_ConnHdlr vc_conn;
1066 f_init();
1067 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001068 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001069 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001070 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001071}
1072
1073
Harald Welte3823e2e2018-02-16 21:53:48 +01001074/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1075private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001076 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001077 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1078
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001079 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001080 f_gmm_auth();
1081 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001082 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001083
Harald Welte955aa942019-05-03 01:29:29 +02001084 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1085 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001086 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001087 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001088 setverdict(pass);
1089}
Harald Welte3823e2e2018-02-16 21:53:48 +01001090testcase TC_attach_combined() runs on test_CT {
1091 var BSSGP_ConnHdlr vc_conn;
1092 f_init();
1093 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001094 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001095 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001096 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001097}
1098
Harald Welte76dee092018-02-16 22:12:59 +01001099/* Attempt of GPRS ATTACH in 'accept all' mode */
1100private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001101 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001102 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1103
1104 g_pars.net.expect_auth := false;
1105
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001106 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001107 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001108 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1109 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001110 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001111 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001112 setverdict(pass);
1113}
1114testcase TC_attach_accept_all() runs on test_CT {
1115 var BSSGP_ConnHdlr vc_conn;
1116 f_init();
1117 f_sleep(1.0);
1118 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001119 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001120 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001121 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001122}
Harald Welte5b7c8122018-02-16 21:48:17 +01001123
Harald Welteb2124b22018-02-16 22:26:56 +01001124/* Attempt of GPRS ATTACH in 'accept all' mode */
1125private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001126 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1127
1128 /* Simulate a foreign IMSI */
1129 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001130 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001131
1132 g_pars.net.expect_auth := false;
1133
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001134 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001135 alt {
1136 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001137 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001138 setverdict(pass);
1139 }
Harald Welte955aa942019-05-03 01:29:29 +02001140 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001141 setverdict(pass);
1142 }
Harald Welte955aa942019-05-03 01:29:29 +02001143 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001144 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001145 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001146 }
Harald Welteb2124b22018-02-16 22:26:56 +01001147 }
1148}
1149testcase TC_attach_closed() runs on test_CT {
1150 var BSSGP_ConnHdlr vc_conn;
1151 f_init();
1152 f_sleep(1.0);
1153 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1154 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001155 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001156 vc_conn.done;
1157 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001158 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001159 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001160 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001161}
1162
Harald Welte04683d02018-02-16 22:43:45 +01001163/* Routing Area Update from Unknown TLLI -> REJECT */
1164private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001165 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1166
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001167 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 +01001168 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001169 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001170 setverdict(pass);
1171 }
1172 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001173 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001174 }
1175}
1176testcase TC_rau_unknown() runs on test_CT {
1177 var BSSGP_ConnHdlr vc_conn;
1178 f_init();
1179 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001180 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001181 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001182 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001183}
1184
Harald Welte91636de2018-02-17 10:16:14 +01001185private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001186 /* first perform regular attach */
1187 f_TC_attach(id);
1188
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001189 f_routing_area_update(g_pars.ra);
1190
Harald Welte91636de2018-02-17 10:16:14 +01001191}
1192testcase TC_attach_rau() runs on test_CT {
1193 var BSSGP_ConnHdlr vc_conn;
1194 f_init();
1195 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001196 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001197 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001198 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001199}
Harald Welte04683d02018-02-16 22:43:45 +01001200
Harald Welte6abb9fe2018-02-17 15:24:48 +01001201/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001202function 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 +02001203 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001204 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001205 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001206 if (expect_purge) {
1207 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1208 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1209 }
1210 T.start;
1211 alt {
1212 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1213 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001214 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001215 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001216 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001217 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001218 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001219 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001220 /* TODO: check if any PDP contexts are deactivated on network side? */
1221 }
1222 [power_off] T.timeout {
1223 setverdict(pass);
1224 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001225 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001226 g_pars.ra := omit;
1227 setverdict(pass);
1228 /* TODO: check if any PDP contexts are deactivated on network side? */
1229 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001230 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001231 if (power_off) {
1232 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1233 } else {
1234 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1235 }
1236 mtc.stop;
1237 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001238 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001239 }
1240}
1241
1242/* IMSI DETACH (non-power-off) for unknown TLLI */
1243private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1244 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1245}
1246testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1247 var BSSGP_ConnHdlr vc_conn;
1248 f_init();
1249 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001250 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001251 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001252 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001253}
1254
1255/* IMSI DETACH (power-off) for unknown TLLI */
1256private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1257 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1258}
1259testcase TC_detach_unknown_poweroff() runs on test_CT {
1260 var BSSGP_ConnHdlr vc_conn;
1261 f_init();
1262 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001263 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001264 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001265 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001266}
1267
1268/* IMSI DETACH (non-power-off) for known TLLI */
1269private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1270 /* first perform regular attach */
1271 f_TC_attach(id);
1272
1273 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1274}
1275testcase TC_detach_nopoweroff() runs on test_CT {
1276 var BSSGP_ConnHdlr vc_conn;
1277 f_init();
1278 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001279 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001280 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001281 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001282}
1283
1284/* IMSI DETACH (power-off) for known TLLI */
1285private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1286 /* first perform regular attach */
1287 f_TC_attach(id);
1288
1289 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1290}
1291testcase TC_detach_poweroff() runs on test_CT {
1292 var BSSGP_ConnHdlr vc_conn;
1293 f_init();
1294 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001295 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001296 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001297 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001298}
1299
Harald Welteeded9ad2018-02-17 20:57:34 +01001300type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001301 BIT3 tid, /* L3 Transaction ID */
1302 BIT4 nsapi, /* SNDCP NSAPI */
1303 BIT4 sapi, /* LLC SAPI */
1304 QoSV qos, /* QoS parameters */
1305 PDPAddressV addr, /* IP address */
1306 octetstring apn optional, /* APN name */
1307 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1308 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001309 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001310 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001311
Harald Welte822f9102018-02-18 20:39:06 +01001312 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1313 OCT4 ggsn_tei_u, /* GGSN TEI User */
1314 octetstring ggsn_ip_c, /* GGSN IP Control */
1315 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001316 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001317
Harald Welte822f9102018-02-18 20:39:06 +01001318 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1319 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1320 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1321 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001322};
1323
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001324
1325private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1326 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1327 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1328 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1329 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1330 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1331 f_gtp_register_teid(apars.ggsn_tei_c);
1332 f_gtp_register_teid(apars.ggsn_tei_u);
1333}
1334
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001335function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001336runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001337 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1338 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001339 var template Recovery_gtpc recovery := omit;
1340
1341 if (send_recovery) {
1342 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1343 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001344
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001345 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 +02001346 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001347 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1348 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1349 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1350 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1351 apars.sgsn_tei_c, apars.gtp_resp_cause,
1352 apars.ggsn_tei_c, apars.ggsn_tei_u,
1353 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001354 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1355 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001356 }
1357 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001358 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001359 setverdict(pass);
1360 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001361 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001362 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001363 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001364 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001365 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001366 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001367 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001368 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001369 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001370 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1371 mtc.stop;
1372 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001373 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001374 setverdict(pass);
1375 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001376 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001377 }
1378}
1379
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001380function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001381runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001382 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1383 var Gtp1cUnitdata g_ud;
1384
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001385 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001386 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1387 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001388 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001389 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1390 }
1391 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001392 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001393 setverdict(pass);
1394 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001395 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001396 }
1397}
1398
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001399function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001400runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001401 var Gtp1cUnitdata g_ud;
1402 var integer seq_nr := 23;
1403 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1404
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001405 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001406 if (error_ind) {
1407 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1408 } else {
1409 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1410 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001411
1412 timer T := 5.0;
1413 T.start;
1414
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001415 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001416 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1417 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001418 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001419 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1420 repeat;
1421 }
1422 [] T.timeout {
1423 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1424 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001425 }
1426}
1427
Harald Welte6f203162018-02-18 22:04:55 +01001428
Harald Welteeded9ad2018-02-17 20:57:34 +01001429/* Table 10.5.156/3GPP TS 24.008 */
1430template (value) QoSV t_QosDefault := {
1431 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1432 delayClass := '100'B, /* best effort */
1433 spare1 := '00'B,
1434 precedenceClass := '010'B, /* normal */
1435 spare2 := '0'B,
1436 peakThroughput := '0000'B, /* subscribed */
1437 meanThroughput := '00000'B, /* subscribed */
1438 spare3 := '000'B,
1439 deliverErroneusSDU := omit,
1440 deliveryOrder := omit,
1441 trafficClass := omit,
1442 maxSDUSize := omit,
1443 maxBitrateUplink := omit,
1444 maxBitrateDownlink := omit,
1445 sduErrorRatio := omit,
1446 residualBER := omit,
1447 trafficHandlingPriority := omit,
1448 transferDelay := omit,
1449 guaranteedBitRateUplink := omit,
1450 guaranteedBitRateDownlink := omit,
1451 sourceStatisticsDescriptor := omit,
1452 signallingIndication := omit,
1453 spare4 := omit,
1454 maxBitrateDownlinkExt := omit,
1455 guaranteedBitRateDownlinkExt := omit,
1456 maxBitrateUplinkExt := omit,
1457 guaranteedBitRateUplinkExt := omit,
1458 maxBitrateDownlinkExt2 := omit,
1459 guaranteedBitRateDownlinkExt2 := omit,
1460 maxBitrateUplinkExt2 := omit,
1461 guaranteedBitRateUplinkExt2 := omit
1462}
1463
1464/* 10.5.6.4 / 3GPP TS 24.008 */
1465template (value) PDPAddressV t_AddrIPv4dyn := {
1466 pdpTypeOrg := '0001'B, /* IETF */
1467 spare := '0000'B,
1468 pdpTypeNum := '21'O, /* IPv4 */
1469 addressInfo := omit
1470}
1471template (value) PDPAddressV t_AddrIPv6dyn := {
1472 pdpTypeOrg := '0001'B, /* IETF */
1473 spare := '0000'B,
1474 pdpTypeNum := '53'O, /* IPv6 */
1475 addressInfo := omit
1476}
1477
Harald Welte37692d82018-02-18 15:21:34 +01001478template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001479 tid := '000'B,
1480 nsapi := '0101'B, /* < 5 are reserved */
1481 sapi := '0011'B, /* 3/5/9/11 */
1482 qos := t_QosDefault,
1483 addr := t_AddrIPv4dyn,
1484 apn := omit,
1485 pco := omit,
1486 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001487 gtp_resp_cause := int2oct(128, 1),
1488 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001489
1490 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001491 ggsn_tei_c := f_rnd_octstring(4),
1492 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001493 ggsn_ip_c := f_inet_addr(ggsn_ip),
1494 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001495 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001496
Harald Welteeded9ad2018-02-17 20:57:34 +01001497 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001498 sgsn_tei_u := omit,
1499 sgsn_ip_c := omit,
1500 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001501}
1502
Harald Welte37692d82018-02-18 15:21:34 +01001503template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1504 connId := 1,
1505 remName := f_inet_ntoa(ip),
1506 remPort := GTP1U_PORT
1507}
1508
1509template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1510 connId := 1,
1511 remName := f_inet_ntoa(ip),
1512 remPort := GTP1C_PORT
1513}
1514
1515private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1516 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1517 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1518}
1519
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001520private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1521 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001522 repeat;
1523 }
1524}
1525
1526template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1527 pDU_SN_UNITDATA := {
1528 nsapi := nsapi,
1529 moreBit := ?,
1530 snPduType := '1'B,
1531 firstSegmentIndicator := ?,
1532 spareBit := ?,
1533 pcomp := ?,
1534 dcomp := ?,
1535 npduNumber := ?,
1536 segmentNumber := ?,
1537 npduNumberContinued := ?,
1538 dataSegmentSnUnitdataPdu := payload
1539 }
1540}
1541
1542/* simple case: single segment, no compression */
1543template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1544 pDU_SN_UNITDATA := {
1545 nsapi := nsapi,
1546 moreBit := '0'B,
1547 snPduType := '1'B,
1548 firstSegmentIndicator := '1'B,
1549 spareBit := '0'B,
1550 pcomp := '0000'B,
1551 dcomp := '0000'B,
1552 npduNumber := '0000'B,
1553 segmentNumber := '0000'B,
1554 npduNumberContinued := '00'O,
1555 dataSegmentSnUnitdataPdu := payload
1556 }
1557}
1558
1559/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001560private 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 +02001561runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001562 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001563 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1564 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001565 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001566 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1567 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001568 [] as_xid(apars, ran_index);
1569 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001570 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1571 [expect_fwd] T.timeout {
1572 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1573 mtc.stop;
1574 }
1575 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1576 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1577 mtc.stop;
1578 }
1579 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001580 }
1581}
1582
Harald Welte64d6b512020-06-17 16:42:00 +02001583/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001584private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001585runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001586 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1587 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1588 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001589 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001590 /* Expect PDU via GTP from SGSN on simulated GGSN */
1591 alt {
1592 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1593 }
1594}
1595
Harald Welteeded9ad2018-02-17 20:57:34 +01001596private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001597 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001598
1599 /* first perform regular attach */
1600 f_TC_attach(id);
1601
1602 f_pdp_ctx_act(apars);
1603}
1604testcase TC_attach_pdp_act() runs on test_CT {
1605 var BSSGP_ConnHdlr vc_conn;
1606 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001607 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001608 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001609 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001610}
Harald Welteb2124b22018-02-16 22:26:56 +01001611
Harald Welte835b15f2018-02-18 14:39:11 +01001612/* PDP Context activation for not-attached subscriber; expect fail */
1613private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001614 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001615 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 +01001616 apars.apn, apars.pco));
1617 alt {
1618 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001619 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001620 setverdict(pass);
1621 }
1622 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1623 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001624 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001625 }
Harald Welte955aa942019-05-03 01:29:29 +02001626 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001627 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001628 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001629 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001630 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001631 }
1632}
1633testcase TC_pdp_act_unattached() runs on test_CT {
1634 var BSSGP_ConnHdlr vc_conn;
1635 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001636 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001637 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001638 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001639}
1640
Harald Welte37692d82018-02-18 15:21:34 +01001641/* ATTACH + PDP CTX ACT + user plane traffic */
1642private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1643 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1644
1645 /* first perform regular attach */
1646 f_TC_attach(id);
1647 /* then activate PDP context */
1648 f_pdp_ctx_act(apars);
1649 /* then transceive a downlink PDU */
1650 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1651 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1652}
1653testcase TC_attach_pdp_act_user() runs on test_CT {
1654 var BSSGP_ConnHdlr vc_conn;
1655 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001656 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001657 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001658 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001659}
1660
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001661/* ATTACH + PDP CTX ACT; reject from GGSN */
1662private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1663 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1664
1665 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1666 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1667
1668 /* first perform regular attach */
1669 f_TC_attach(id);
1670 /* then activate PDP context */
1671 f_pdp_ctx_act(apars);
1672}
1673testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1674 var BSSGP_ConnHdlr vc_conn;
1675 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001676 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001677 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001678 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001679}
Harald Welte835b15f2018-02-18 14:39:11 +01001680
Harald Welte6f203162018-02-18 22:04:55 +01001681/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1682private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1683 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1684
1685 /* first perform regular attach */
1686 f_TC_attach(id);
1687 /* then activate PDP context */
1688 f_pdp_ctx_act(apars);
1689 /* then transceive a downlink PDU */
1690 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1691 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1692
1693 f_pdp_ctx_deact_mo(apars, '00'O);
1694}
1695testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1696 var BSSGP_ConnHdlr vc_conn;
1697 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001698 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 +01001699 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001700 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001701}
1702
Harald Welte57b9b7f2018-02-18 22:28:13 +01001703/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1704private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1705 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1706
1707 /* first perform regular attach */
1708 f_TC_attach(id);
1709 /* then activate PDP context */
1710 f_pdp_ctx_act(apars);
1711 /* then transceive a downlink PDU */
1712 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1713 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1714
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001715 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001716}
1717testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1718 var BSSGP_ConnHdlr vc_conn;
1719 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001720 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 +01001721 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001722 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001723}
1724
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001725/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1726private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1727 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1728 var Gtp1cUnitdata g_ud;
1729 var integer i;
1730 var OCT1 cause_regular_deact := '24'O;
1731
1732 /* first perform regular attach + PDP context act */
1733 f_TC_attach(id);
1734 f_pdp_ctx_act(apars);
1735
1736 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1737 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1738
1739 for (i := 0; i < 2; i := i+1) {
1740 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1741 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1742 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1743 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1744 }
1745 }
1746
1747 alt {
1748 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1749 setverdict(pass);
1750 }
1751 [] as_xid(apars, 0);
1752 }
1753
1754 /* Make sure second DeactPdpAccept is sent: */
1755 timer T := 2.0;
1756 T.start;
1757 alt {
1758 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1759 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1760 }
1761 [] T.timeout {
1762 setverdict(pass);
1763 }
1764 }
1765
1766 setverdict(pass);
1767}
1768testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1769 var BSSGP_ConnHdlr vc_conn;
1770 f_init();
1771 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1772 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001773 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001774}
1775
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001776/* ATTACH + ATTACH (2nd) */
1777private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1778 g_pars.t_guard := 5.0;
1779
1780 /* first perform regular attach */
1781 f_TC_attach(id);
1782
1783 /* second to perform regular attach */
1784 f_TC_attach(id);
1785}
1786
1787
1788testcase TC_attach_second_attempt() runs on test_CT {
1789 var BSSGP_ConnHdlr vc_conn;
1790 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001791 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001792 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001793 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001794}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001795
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001796private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1797 var Gtp1cUnitdata g_ud;
1798 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1799 var integer seq_nr;
1800
1801 /* first perform regular attach */
1802 f_TC_attach(id);
1803 /* then activate PDP context */
1804 f_pdp_ctx_act(apars);
1805
1806 /* Wait to receive first echo request and send initial Restart counter */
1807 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1808 BSSGP[0].clear;
1809 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1810 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1811 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1812 }
1813
1814 /* At some point next echo request not answered will timeout and SGSN
1815 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1816 timer T := 3.0 * 6.0 + 16.0;
1817 T.start;
1818 alt {
1819 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1820 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1821 setverdict(pass);
1822 }
1823 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1824 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1825 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1826 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1827 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1828 repeat;
1829 }
1830 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1831 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1832 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1833 repeat;
1834 }
1835 [] T.timeout {
1836 setverdict(fail, "BSSGP DeactPdpReq not received");
1837 mtc.stop;
1838 }
1839 [] as_xid(apars);
1840 }
1841 T.stop
1842
1843 setverdict(pass);
1844}
1845/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1846testcase TC_attach_echo_timeout() runs on test_CT {
1847 var BSSGP_ConnHdlr vc_conn;
1848 g_use_echo := true;
1849 f_init();
1850 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1851 vc_conn.done;
1852 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001853 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001854}
1855
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001856private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001857 var Gtp1cUnitdata g_ud;
1858 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1859
1860 /* first perform regular attach */
1861 f_TC_attach(id);
1862 /* Activate a pdp context against the GGSN */
1863 f_pdp_ctx_act(apars);
1864 /* Wait to receive first echo request and send initial Restart counter */
1865 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1866 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1867 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1868 }
1869 /* Wait to receive second echo request and send incremented Restart
1870 counter. This will fake a restarted GGSN, and pdp ctx allocated
1871 should be released by SGSN */
1872 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1873 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1874 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1875 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1876 }
1877 var OCT1 cause_network_failure := int2oct(38, 1)
1878 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001879 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001880 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001881 setverdict(pass);
1882 }
1883 [] as_xid(apars);
1884 }
1885 setverdict(pass);
1886}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001887/* ATTACH + trigger Recovery procedure through EchoResp */
1888testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001889 var BSSGP_ConnHdlr vc_conn;
1890 g_use_echo := true
1891 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001892 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 +02001893 vc_conn.done;
1894 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001895 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001896}
1897
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001898private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1899 var Gtp1cUnitdata g_ud;
1900 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1901 var integer seq_nr := 23;
1902 var GtpPeer peer;
1903 /* first perform regular attach */
1904 f_TC_attach(id);
1905
1906 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1907 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1908 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1909 f_pdp_ctx_act(apars, true);
1910
1911 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1912/* received. */
1913 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1914
1915 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1916 would be great to have an active pdp context here before triggering
1917 Recovery, and making sure the the DEACT request is sent by the SGSN.
1918 */
1919
1920 /* Activate a pdp context against the GGSN, send incremented Recovery
1921 IE. This should trigger the recovery path, but still this specific
1922 CTX activation should work. */
1923 apars.exp_rej_cause := omit; /* default value for tests */
1924 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1925 f_pdp_ctx_act(apars, true);
1926
1927 setverdict(pass);
1928}
1929/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1930testcase TC_attach_restart_ctr_create() runs on test_CT {
1931 var BSSGP_ConnHdlr vc_conn;
1932 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001933 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 +02001934 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001935 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001936}
1937
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001938/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1939private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1940 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1941 var integer seq_nr := 23;
1942 var GtpPeer peer;
1943 var integer i;
1944
1945 /* first perform regular attach */
1946 f_TC_attach(id);
1947 /* then activate PDP context */
1948 f_pdp_ctx_act(apars);
1949
Alexander Couzens0e510e62018-07-28 23:06:00 +02001950 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001951 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1952 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1953
1954 for (i := 0; i < 5; i := i+1) {
1955 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001956 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001957 [] as_xid(apars);
1958 }
1959 }
1960
1961 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1962
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001963 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001964 setverdict(pass);
1965}
1966testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1967 var BSSGP_ConnHdlr vc_conn;
1968 f_init();
1969 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001970 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 +02001971 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001972 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001973}
1974
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001975/* ATTACH + PDP CTX ACT dropped + retrans */
1976private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1977 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1978 var Gtp1cUnitdata g_ud_first, g_ud_second;
1979 /* first perform regular attach */
1980 f_TC_attach(id);
1981
1982 /* then activate PDP context on the Gb side */
1983 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1984 apars.apn, apars.pco), 0);
1985
1986 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1987 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1988 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1989 if (g_ud_first != g_ud_second) {
1990 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1991 mtc.stop;
1992 }
1993 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1994 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1995 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1996 apars.sgsn_tei_c, apars.gtp_resp_cause,
1997 apars.ggsn_tei_c, apars.ggsn_tei_u,
1998 apars.nsapi,
1999 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2000 omit, omit));
2001 }
Harald Welte955aa942019-05-03 01:29:29 +02002002 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002003
2004 /* Now the same with Deact */
2005 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2006 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2007 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2008 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2009 if (g_ud_first != g_ud_second) {
2010 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2011 mtc.stop;
2012 }
2013 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2014 BSSGP[0].clear;
2015 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2016 }
2017 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002018 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002019 setverdict(pass);
2020 }
2021 [] as_xid(apars, 0);
2022 }
2023
2024 setverdict(pass);
2025}
2026testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2027 var BSSGP_ConnHdlr vc_conn;
2028 f_init();
2029 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2030 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002031 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002032}
2033
2034/* Test that SGSN GTP response retransmit queue works fine */
2035private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2036 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2037 var integer seq_nr := 23;
2038 var Gtp1cUnitdata g_ud_first, g_ud_second;
2039 var template Gtp1cUnitdata g_delete_req;
2040 /* first perform regular attach + PDP context act */
2041 f_TC_attach(id);
2042 f_pdp_ctx_act(apars);
2043
2044 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2045 BSSGP[0].clear;
2046 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2047 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2048 GTP.send(g_delete_req);
2049 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002050 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002051 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2052 }
2053 [] as_xid(apars, 0);
2054 }
2055 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2056 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2057 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2058 mtc.stop;
2059 }
2060 };
2061
2062 /* Send duplicate DeleteCtxReq */
2063 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2064 GTP.send(g_delete_req);
2065 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2066 if (g_ud_first != g_ud_second) {
2067 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2068 mtc.stop;
2069 }
2070 }
2071
2072 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2073 * is handled differently by SGSN (expect "non-existent" cause) */
2074 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2075 GTP.send(g_delete_req);
2076 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2077 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2078 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2079 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2080 mtc.stop;
2081 }
2082 }
2083
2084 setverdict(pass);
2085}
2086testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2087 var BSSGP_ConnHdlr vc_conn;
2088 f_init();
2089 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2090 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002091 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002092}
2093
Alexander Couzens5e307b42018-05-22 18:12:20 +02002094private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2095 /* MS: perform regular attach */
2096 f_TC_attach(id);
2097
2098 /* HLR: cancel the location request */
2099 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2100 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002101
2102 /* ensure no Detach Request got received */
2103 timer T := 5.0;
2104 T.start;
2105 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002106 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002107 T.stop;
2108 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002109 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002110 }
2111 [] T.timeout {
2112 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002113 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002114 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002115 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002116 repeat;
2117 }
2118 }
2119}
2120
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002121/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2122private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2123 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2124
2125 /* first perform regular attach */
2126 f_TC_attach(id);
2127 /* then activate PDP context */
2128 f_pdp_ctx_act(apars);
2129 /* then transceive a downlink PDU */
2130 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2131
2132 /* Send Error indication as response from upload PDU and expect deact towards MS */
2133 f_pdp_ctx_deact_mt(apars, true);
2134}
2135testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2136 var BSSGP_ConnHdlr vc_conn;
2137 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002138 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 +02002139 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002140 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002141}
2142
Alexander Couzens5e307b42018-05-22 18:12:20 +02002143testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2144 /* MS <-> SGSN: GMM Attach
2145 * HLR -> SGSN: Cancel Location Request
2146 * HLR <- SGSN: Cancel Location Ack
2147 */
2148 var BSSGP_ConnHdlr vc_conn;
2149 f_init();
2150 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002151 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002152 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002153 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002154}
2155
2156
Alexander Couzensc87967a2018-05-22 16:09:54 +02002157private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2158 /* MS: perform regular attach */
2159 f_TC_attach(id);
2160
2161 /* HLR: cancel the location request */
2162 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2163 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2164 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2165
2166 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002167 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002168 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002169
2170 setverdict(pass);
2171}
2172
2173testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2174 /* MS <-> SGSN: GMM Attach
2175 * HLR -> SGSN: Cancel Location Request
2176 * HLR <- SGSN: Cancel Location Ack
2177 * MS <- SGSN: Detach Request
2178 * SGSN-> MS: Detach Complete
2179 */
2180 var BSSGP_ConnHdlr vc_conn;
2181 f_init();
2182 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002183 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002184 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002185 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002186}
2187
2188
Alexander Couzens6c47f292018-05-22 17:09:49 +02002189private function f_hlr_location_cancel_request_unknown_subscriber(
2190 charstring id,
2191 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2192
2193 /* HLR: cancel the location request */
2194 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2195
2196 /* cause 2 = IMSI_UNKNOWN */
2197 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2198
2199 setverdict(pass);
2200}
2201
2202private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002203 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002204}
2205
2206testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2207 /* HLR -> SGSN: Cancel Location Request
2208 * HLR <- SGSN: Cancel Location Error
2209 */
2210
2211 var BSSGP_ConnHdlr vc_conn;
2212 f_init();
2213 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002214 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 +02002215 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002216 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002217}
2218
2219private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002220 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002221}
2222
2223testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2224 /* HLR -> SGSN: Cancel Location Request
2225 * HLR <- SGSN: Cancel Location Error
2226 */
2227
2228 var BSSGP_ConnHdlr vc_conn;
2229 f_init();
2230 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002231 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 +02002232 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002233 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002234}
2235
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002236private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2237 f_TC_attach(id);
2238 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2239}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002240
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002241testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2242 /* MS <-> SGSN: Attach
2243 * MS -> SGSN: Detach Req (Power off)
2244 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2245 */
2246 var BSSGP_ConnHdlr vc_conn;
2247 var integer id := 33;
2248 var charstring imsi := hex2str(f_gen_imsi(id));
2249
2250 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002251 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002252 vc_conn.done;
2253
2254 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002255 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002256}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002257
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002258/* Attempt an attach, but loose the Identification Request (IMEI) */
2259private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2260 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002261 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002262
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002263 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 +02002264
2265 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002266 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002267 /* break */
2268 }
Harald Welte955aa942019-05-03 01:29:29 +02002269 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002270 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002271 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002272 repeat;
2273 }
Harald Welte955aa942019-05-03 01:29:29 +02002274 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002275 /* ignore ID REQ IMEI */
2276 count_req := count_req + 1;
2277 repeat;
2278 }
2279 }
2280 if (count_req != 5) {
2281 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002282 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002283 }
2284 setverdict(pass);
2285}
2286
2287testcase TC_attach_no_imei_response() runs on test_CT {
2288 /* MS -> SGSN: Attach Request IMSI
2289 * MS <- SGSN: Identity Request IMSI (optional)
2290 * MS -> SGSN: Identity Response IMSI (optional)
2291 * MS <- SGSN: Identity Request IMEI
2292 * MS -x SGSN: no response
2293 * MS <- SGSN: re-send: Identity Request IMEI 4x
2294 * MS <- SGSN: Attach Reject
2295 */
2296 var BSSGP_ConnHdlr vc_conn;
2297 f_init();
2298 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002299 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 +02002300 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002301 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002302}
2303
Alexander Couzens53f20562018-06-12 16:24:12 +02002304/* Attempt an attach, but loose the Identification Request (IMSI) */
2305private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2306 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002307 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002308
2309 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2310 g_pars.p_tmsi := 'c0000035'O;
2311
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002312 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), f_random_RAI(), true, false, omit, omit));
Alexander Couzens53f20562018-06-12 16:24:12 +02002313
2314 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002315 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002316 /* break */
2317 }
Harald Welte955aa942019-05-03 01:29:29 +02002318 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002319 /* ignore ID REQ IMSI */
2320 count_req := count_req + 1;
2321 repeat;
2322 }
Harald Welte955aa942019-05-03 01:29:29 +02002323 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002324 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002325 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002326 repeat;
2327 }
2328 }
2329 if (count_req != 5) {
2330 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002331 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002332 }
2333 setverdict(pass);
2334}
2335
2336testcase TC_attach_no_imsi_response() runs on test_CT {
2337 /* MS -> SGSN: Attach Request TMSI (unknown)
2338 * MS <- SGSN: Identity Request IMEI (optional)
2339 * MS -> SGSN: Identity Response IMEI (optional)
2340 * MS <- SGSN: Identity Request IMSI
2341 * MS -x SGSN: no response
2342 * MS <- SGSN: re-send: Identity Request IMSI 4x
2343 * MS <- SGSN: Attach Reject
2344 */
2345 var BSSGP_ConnHdlr vc_conn;
2346 f_init();
2347 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002348 vc_conn := f_start_handler(refers(f_TC_attach_no_imsi_response), testcasename(), g_gb, 35, 60.0);
Alexander Couzens53f20562018-06-12 16:24:12 +02002349 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002350 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002351}
2352
Alexander Couzenscf818962018-06-05 18:00:00 +02002353private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2354 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2355}
2356
2357testcase TC_attach_check_subscriber_list() runs on test_CT {
2358 /* MS <-> SGSN: Attach
2359 * VTY -> SGSN: Check if MS is in subscriber cache
2360 */
2361 var BSSGP_ConnHdlr vc_conn;
2362 var integer id := 34;
2363 var charstring imsi := hex2str(f_gen_imsi(id));
2364
2365 f_init();
2366 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002367 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002368 vc_conn.done;
2369
2370 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2371 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002372 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002373}
2374
Alexander Couzensf9858652018-06-07 16:14:53 +02002375private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2376 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002377 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002378
2379 /* unregister the old IMSI */
2380 f_bssgp_client_unregister(g_pars.imsi);
2381 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002382 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002383 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002384
2385 /* there is no auth */
2386 g_pars.net.expect_auth := false;
2387
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002388 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002389 f_gmm_auth();
2390 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002391 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002392 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002393 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002394 }
Harald Welte955aa942019-05-03 01:29:29 +02002395 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2396 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002397 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002398 setverdict(pass);
2399 }
2400 }
2401}
Alexander Couzens03d12242018-08-07 16:13:52 +02002402
2403private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2404
2405 f_TC_attach_closed_foreign(id);
2406 f_TC_attach_closed_imsi_added(id);
2407
2408}
2409
2410
Alexander Couzensf9858652018-06-07 16:14:53 +02002411testcase TC_attach_closed_add_vty() runs on test_CT {
2412 /* VTY-> SGSN: policy close
2413 * MS -> SGSN: Attach Request
2414 * MS <- SGSN: Identity Request IMSI
2415 * MS -> SGSN: Identity Response IMSI
2416 * MS <- SGSN: Attach Reject
2417 * VTY-> SGSN: policy imsi-acl add IMSI
2418 * MS -> SGSN: Attach Request
2419 * MS <- SGSN: Identity Request IMSI
2420 * MS -> SGSN: Identity Response IMSI
2421 * MS <- SGSN: Identity Request IMEI
2422 * MS -> SGSN: Identity Response IMEI
2423 * MS <- SGSN: Attach Accept
2424 */
2425 var BSSGP_ConnHdlr vc_conn;
2426 f_init();
2427 f_sleep(1.0);
2428 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2429 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002430 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2431 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002432 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002433 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002434 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002435 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002436}
2437
Alexander Couzens0085bd72018-06-12 19:08:44 +02002438/* Attempt an attach, but never answer a Attach Complete */
2439private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2440 var integer count_req := 0;
2441
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002442 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 +02002443 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002444 /* Expect SGSN to perform LU with HLR */
2445 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002446
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002447 timer T := 10.0;
2448 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002449 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002450 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002451 /* break */
2452 }
Harald Welte955aa942019-05-03 01:29:29 +02002453 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002454 /* ignore */
2455 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002456 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002457 repeat;
2458 }
2459 }
2460 if (count_req != 5) {
2461 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002462 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002463 }
2464 setverdict(pass);
2465}
2466
2467testcase TC_attach_check_complete_resend() runs on test_CT {
2468 /* MS -> SGSN: Attach Request IMSI
2469 * MS <- SGSN: Identity Request *
2470 * MS -> SGSN: Identity Response *
2471 * MS <- SGSN: Attach Complete 5x
2472 */
2473 var BSSGP_ConnHdlr vc_conn;
2474 f_init();
2475 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002476 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 +02002477 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002478 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002479}
2480
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002481friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002482 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002483 var PDU_DTAP_PS_MT mt;
2484 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002485
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002486 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002487 p_tmsi := g_pars.p_tmsi;
2488 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002489 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002490 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 +02002491 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002492 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2493 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2494 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002495 setverdict(pass);
2496 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002497 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2498 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2499 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002500 setverdict(pass);
2501 }
2502
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002503 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002504 setverdict(fail, "Unexpected RAU Reject");
2505 mtc.stop;
2506 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002507 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002508 setverdict(fail, "Unexpected RAU Reject");
2509 mtc.stop;
2510 }
2511
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002512 [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 +02002513 key_sts := ?)) {
2514 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2515 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002516 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002517 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002518 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002519 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2520 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002521 }
2522}
2523
Alexander Couzensbfda9212018-07-31 03:17:33 +02002524private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002525 /* first perform regular attach */
2526 f_TC_attach(id);
2527
2528 /* then send RAU */
2529 f_routing_area_update(g_pars.ra);
2530
2531 /* do another RAU */
2532 f_routing_area_update(g_pars.ra);
2533
2534 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2535}
2536
2537testcase TC_attach_rau_a_a() runs on test_CT {
2538 /* MS <-> SGSN: Successful Attach
2539 * MS -> SGSN: Routing Area Update Request
2540 * MS <- SGSN: Routing Area Update Accept
2541 * MS -> SGSN: Routing Area Update Request
2542 * MS <- SGSN: Routing Area Update Accept
2543 * MS -> SGSN: Detach (PowerOff)
2544 */
2545 var BSSGP_ConnHdlr vc_conn;
2546 f_init();
2547 f_sleep(1.0);
2548 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2549 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002550 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002551}
2552
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002553private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002554 f_TC_attach(id);
2555
2556 log("attach complete sending rau");
2557 f_routing_area_update(g_pars.ra, 0);
2558
2559 log("rau complete unregistering");
2560 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002561 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002562
2563 log("sending second RAU via different RA");
2564 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2565
2566 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2567}
2568
2569testcase TC_attach_rau_a_b() runs on test_CT {
2570 /* MS <-> SGSN: Successful Attach
2571 * MS -> SGSN: Routing Area _a_ Update Request
2572 * MS <- SGSN: Routing Area _a_ Update Accept
2573 * MS -> SGSN: Routing Area _b_ Update Request
2574 * MS <- SGSN: Routing Area _b_ Update Accept
2575 * MS -> SGSN: Detach (PowerOff)
2576 */
2577 var BSSGP_ConnHdlr vc_conn;
2578 f_init();
2579 f_sleep(1.0);
2580 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2581 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002582 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002583}
2584
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002585private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2586 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002587 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002588 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002589 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002590
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002591 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002592
2593 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002594 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002595 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2596 mtc.stop;
2597 }
Harald Welte955aa942019-05-03 01:29:29 +02002598 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002599 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002600 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002601 repeat;
2602 }
Harald Welte955aa942019-05-03 01:29:29 +02002603 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002604 /* send out a second GMM_Attach Request.
2605 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2606 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002607 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002608 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002609 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002610 }
2611 }
2612 f_sleep(1.0);
2613
2614 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2615 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002616 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002617 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002618 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002619 repeat;
2620 }
Harald Welte955aa942019-05-03 01:29:29 +02002621 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002622 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2623 mtc.stop;
2624 }
Harald Welte955aa942019-05-03 01:29:29 +02002625 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002626 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2627 mtc.stop;
2628 }
Harald Welte955aa942019-05-03 01:29:29 +02002629 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2630 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002631 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002632 setverdict(pass);
2633 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2634 }
2635 }
2636}
2637
2638testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2639 /* Testing if the SGSN ignore Attach Request with the exact same content */
2640 /* MS -> SGSN: Attach Request IMSI
2641 * MS <- SGSN: Identity Request IMSI (optional)
2642 * MS -> SGSN: Identity Response IMSI (optional)
2643 * MS <- SGSN: Identity Request IMEI
2644 * MS -> SGSN: Attach Request (2nd)
2645 * MS <- SGSN: Identity Response IMEI
2646 * MS <- SGSN: Attach Accept
2647 * MS -> SGSN: Attach Complete
2648 */
2649 var BSSGP_ConnHdlr vc_conn;
2650 f_init();
2651 f_sleep(1.0);
2652 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2653 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2654 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002655 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002656}
2657
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002658private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002659 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2660
2661 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2662
2663 /* send Attach Request */
2664 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2665 * 3G auth vectors */
2666 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2667 /* The thing is, if the solSACapability is 'omit', then the
2668 * revisionLevelIndicatior is at the wrong place! */
2669 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002670 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002671
2672 /* do the auth */
2673 var PDU_L3_MS_SGSN l3_mo;
2674 var PDU_L3_SGSN_MS l3_mt;
2675 var default di := activate(as_mm_identity());
2676
2677 var GSUP_IE auth_tuple;
2678 var template AuthenticationParameterAUTNTLV autn;
2679
2680 g_pars.vec := f_gen_auth_vec_3g();
2681 autn := {
2682 elementIdentifier := '28'O,
2683 lengthIndicator := lengthof(g_pars.vec.autn),
2684 autnValue := g_pars.vec.autn
2685 };
2686 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2687 g_pars.vec.sres,
2688 g_pars.vec.kc,
2689 g_pars.vec.ik,
2690 g_pars.vec.ck,
2691 g_pars.vec.autn,
2692 g_pars.vec.res));
2693 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2694 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2695 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2696
2697 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2698 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002699 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002700
2701 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002702 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002703
2704 /* wait for the GSUP resync request */
2705 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2706 g_pars.imsi,
2707 g_pars.vec.auts,
2708 g_pars.vec.rand));
2709
2710 /* generate new key material */
2711 g_pars.vec := f_gen_auth_vec_3g();
2712 autn := {
2713 elementIdentifier := '28'O,
2714 lengthIndicator := lengthof(g_pars.vec.autn),
2715 autnValue := g_pars.vec.autn
2716 };
2717
2718 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2719 g_pars.vec.sres,
2720 g_pars.vec.kc,
2721 g_pars.vec.ik,
2722 g_pars.vec.ck,
2723 g_pars.vec.autn,
2724 g_pars.vec.res));
2725 /* send new key material */
2726 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2727
2728 /* wait for the new Auth Request */
2729 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2730 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002731 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002732 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2733 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2734 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2735 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2736 valueField := substr(g_pars.vec.res, 0, 4)
2737 };
2738 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2739 elementIdentifier := '21'O,
2740 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2741 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2742 };
2743 l3_mo := valueof(auth_ciph_resp);
2744 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2745 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2746 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2747 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2748 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002749 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002750 deactivate(di);
2751
2752 /* Expect SGSN to perform LU with HLR */
2753 f_gmm_gsup_lu_isd();
2754
Harald Welte955aa942019-05-03 01:29:29 +02002755 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2756 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002757 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002758 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002759 setverdict(pass);
2760}
2761
2762testcase TC_attach_usim_resync() runs on test_CT {
2763 /* MS -> SGSN: Attach Request
2764 * MS <- SGSN: Identity Request IMSI
2765 * MS -> SGSN: Identity Response IMSI
2766 * MS <- SGSN: Identity Request IMEI
2767 * MS -> SGSN: Identity Response IMEI
2768 * HLR<- SGSN: SAI Request
2769 * HLR-> SGSN: SAI Response
2770 * MS <- SGSN: Auth Request
2771 * MS -> SGSN: Auth Failure (with AUTS)
2772 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2773 * HLR-> SGSN: SAI Response (new key material)
2774 * MS <- SGSN: Auth Request (new key material)
2775 * MS -> SGSN: Auth Response
2776 * MS <- SGSN: Attach Accept
2777 * MS -> SGSN: Attach Complete
2778 */
2779 var BSSGP_ConnHdlr vc_conn;
2780 f_init();
2781 f_sleep(1.0);
2782 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2783 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002784 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002785}
2786
Harald Weltea05b8072019-04-23 22:35:05 +02002787
2788/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2789private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2790 f_gmm_attach(false, false);
2791 f_sleep(1.0);
2792 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2793 /* try to detach to check if SGSN is still alive */
2794 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2795}
2796testcase TC_llc_null() runs on test_CT {
2797 var BSSGP_ConnHdlr vc_conn;
2798 f_init();
2799 f_sleep(1.0);
2800 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2801 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002802 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002803}
2804
Harald Welte645a1512019-04-23 23:18:23 +02002805/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2806private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2807 f_gmm_attach(false, false);
2808 f_sleep(1.0);
2809 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002810 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002811 setverdict(pass);
2812}
2813testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2814 var BSSGP_ConnHdlr vc_conn;
2815 f_init();
2816 f_sleep(1.0);
2817 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2818 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002819 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002820}
2821
2822/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2823private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2824 f_gmm_attach(false, false);
2825 f_sleep(1.0);
2826 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002827 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002828 setverdict(pass);
2829}
2830testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2831 var BSSGP_ConnHdlr vc_conn;
2832 f_init();
2833 f_sleep(1.0);
2834 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2835 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002836 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002837}
2838
Harald Welte2aaac1b2019-05-02 10:02:53 +02002839/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2840private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2841 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2842 var template (value) XID_Information xid;
2843 var template XID_Information xid_rx;
2844
2845 /* first perform regular attach */
2846 f_TC_attach(id);
2847 /* then activate PDP context */
2848 f_pdp_ctx_act(apars);
2849
2850 /* start MO XID */
2851 xid := { ts_XID_L3(''O) };
2852 xid_rx := { tr_XID_L3(''O) };
2853 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2854 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002855 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002856 [] as_xid(apars);
2857 }
2858 setverdict(pass);
2859}
2860testcase TC_xid_empty_l3() runs on test_CT {
2861 var BSSGP_ConnHdlr vc_conn;
2862 f_init();
2863 f_sleep(1.0);
2864 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2865 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002866 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002867}
2868
2869private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2870 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2871 var template (value) XID_Information xid;
2872 var template XID_Information xid_rx;
2873
2874 /* first perform regular attach */
2875 f_TC_attach(id);
2876 /* then activate PDP context */
2877 f_pdp_ctx_act(apars);
2878
2879 /* start MO XID */
2880 xid := { ts_XID_N201U(1234) };
2881 xid_rx := { tr_XID_N201U(1234) };
2882 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2883 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002884 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002885 [] as_xid(apars);
2886 }
2887 setverdict(pass);
2888}
2889testcase TC_xid_n201u() runs on test_CT {
2890 var BSSGP_ConnHdlr vc_conn;
2891 f_init();
2892 f_sleep(1.0);
2893 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2894 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002895 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002896}
2897
Alexander Couzens6bee0872019-05-11 01:48:50 +02002898private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2899 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2900
2901 /* first perform regular attach */
2902 f_TC_attach(id);
2903 /* then activate PDP context */
2904 f_pdp_ctx_act(apars);
2905 /* do a normal detach */
2906 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2907}
2908
2909testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2910 /* MS -> SGSN: Attach Request
2911 * MS <-> SGSN: [..]
2912 * MS -> SGSN: Attach Complete
2913 * MS -> SGSN: PDP Activate Request
2914 * MS <- SGSN: PDP Activate Accept
2915 * MS -> SGSN: GMM Detach Request
2916 * MS <- SGSN: GMM Detach Accept
2917 */
2918 var BSSGP_ConnHdlr vc_conn;
2919 f_init();
2920 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2921 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002922 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002923}
Harald Welte645a1512019-04-23 23:18:23 +02002924
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002925private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2926 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2927 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2928 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2929 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2930 var PDU_L3_SGSN_MS l3_mt;
2931
2932 f_send_l3(attach_req, 0);
2933
2934 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2935
2936 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2937 alt {
2938 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2939 setverdict(pass);
2940 }
2941 [] BSSGP[0].receive { repeat; }
2942 }
2943}
2944
2945/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2946 * See OS#3957 and OS#4245 for more information.
2947 */
2948testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2949 /*
2950 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2951 * MS <-- SGSN: Identity Request (IMEI)
2952 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2953 */
2954 var BSSGP_ConnHdlr vc_conn;
2955 f_init();
2956 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2957 vc_conn.done;
2958 f_cleanup();
2959}
2960
Harald Welte8e5932e2020-06-17 22:12:54 +02002961private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2962var PDU_BSSGP rx;
2963[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2964 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2965 mtc.stop;
2966 }
2967}
2968
2969/* SUSPEND, then DL traffic: should not pass + no paging expected */
2970private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2971 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2972 var default d;
2973
2974 /* first perform regular attach */
2975 f_TC_attach(id);
2976 /* then activate PDP context */
2977 f_pdp_ctx_act(apars);
2978 /* then transceive a downlink PDU */
2979 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2980
2981 /* now suspend GPRS */
2982 f_bssgp_suspend();
2983
2984 d := activate(as_nopaging_ps());
2985
2986 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2987 * nor any related paging requests */
2988 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
2989
2990 deactivate(d);
2991}
2992testcase TC_suspend_nopaging() runs on test_CT {
2993 var BSSGP_ConnHdlr vc_conn;
2994 f_init();
2995 f_sleep(1.0);
2996 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
2997 vc_conn.done;
2998 f_cleanup();
2999}
3000
3001
3002/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3003private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3004 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3005 var OCT1 susp_ref;
3006 var default d;
3007
3008 /* first perform regular attach */
3009 f_TC_attach(id);
3010 /* then activate PDP context */
3011 f_pdp_ctx_act(apars);
3012 /* then transceive a downlink PDU */
3013 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3014
3015 /* now suspend GPRS */
3016 susp_ref := f_bssgp_suspend();
3017
3018 d := activate(as_nopaging_ps());
3019
3020 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3021 * nor any related paging requests */
3022 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3023
3024 deactivate(d);
3025
3026 /* resume GPRS */
3027 f_bssgp_resume(susp_ref);
3028
3029 /* now data should be flowing again */
3030 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3031}
3032testcase TC_suspend_resume() runs on test_CT {
3033 var BSSGP_ConnHdlr vc_conn;
3034 f_init();
3035 f_sleep(1.0);
3036 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3037 vc_conn.done;
3038 f_cleanup();
3039}
3040
3041/* SUSPEND, then RAU: data expected to flow after implicit resume */
3042private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3043 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3044 var default d;
3045
3046 /* first perform regular attach */
3047 f_TC_attach(id);
3048 /* then activate PDP context */
3049 f_pdp_ctx_act(apars);
3050 /* then transceive a downlink PDU */
3051 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3052
3053 /* now suspend GPRS */
3054 f_bssgp_suspend();
3055
3056 d := activate(as_nopaging_ps());
3057
3058 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3059 * nor any related paging requests */
3060 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3061
3062 deactivate(d);
3063
3064 /* perform RAU (implicit RESUME) */
3065 f_routing_area_update(g_pars.ra);
3066
3067 /* now data should be flowing again */
3068 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3069
3070}
3071testcase TC_suspend_rau() runs on test_CT {
3072 var BSSGP_ConnHdlr vc_conn;
3073 f_init();
3074 f_sleep(1.0);
3075 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3076 vc_conn.done;
3077 f_cleanup();
3078}
3079
3080
3081/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3082private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3083 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3084 var default d;
3085
3086 /* first perform regular attach */
3087 f_TC_attach(id);
3088 /* then activate PDP context */
3089 f_pdp_ctx_act(apars);
3090 /* then transceive a downlink PDU */
3091 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3092
3093 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3094 f_sleep(5.0);
3095
3096 /* now data should be flowing again, but with PS PAGING */
3097 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3098 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3099
3100 /* FIXME: simulate paging response */
3101 /* FIXME: verify PDU actually arrives only after paging response was successful */
3102
3103}
3104testcase TC_paging_ps() runs on test_CT {
3105 var BSSGP_ConnHdlr vc_conn;
3106 f_init();
3107 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3108 f_sleep(1.0);
3109 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3110 vc_conn.done;
3111 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3112 f_cleanup();
3113}
3114
3115
3116
3117
3118
Harald Welte5ac31492018-02-15 20:39:13 +01003119control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003120 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003121 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003122 execute( TC_attach_umts_aka_umts_res() );
3123 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003124 execute( TC_attach_auth_id_timeout() );
3125 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003126 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003127 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003128 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003129 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003130 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003131 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003132 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003133 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003134 execute( TC_attach_closed_add_vty(), 20.0 );
3135 execute( TC_attach_check_subscriber_list(), 20.0 );
3136 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003137 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003138 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3139 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3140 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3141 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003142 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003143 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003144 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003145 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003146 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003147 execute( TC_detach_unknown_nopoweroff() );
3148 execute( TC_detach_unknown_poweroff() );
3149 execute( TC_detach_nopoweroff() );
3150 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003151 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003152 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003153 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003154 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003155 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003156 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003157 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003158 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003159 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003160 execute( TC_attach_restart_ctr_echo() );
3161 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003162 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003163 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3164 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003165 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003166 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003167 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003168
Harald Welte2aaac1b2019-05-02 10:02:53 +02003169 execute( TC_xid_empty_l3() );
3170 execute( TC_xid_n201u() );
3171
Harald Weltea05b8072019-04-23 22:35:05 +02003172 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003173 execute( TC_llc_sabm_dm_llgmm() );
3174 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003175
Harald Welte8e5932e2020-06-17 22:12:54 +02003176 execute( TC_suspend_nopaging() );
3177 execute( TC_suspend_resume() );
3178 execute( TC_suspend_rau() );
3179 execute( TC_paging_ps() );
3180
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003181 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3182 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003183}
Harald Welte96a33b02018-02-04 10:36:22 +01003184
3185
3186
3187}