blob: 4b4bbd9871c2a750cc389bdd8b7e01eba951d0f4 [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;
15
Harald Welte96a33b02018-02-04 10:36:22 +010016import from General_Types all;
17import from Osmocom_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010018import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010019import from NS_Types all;
20import from NS_Emulation all;
21import from BSSGP_Types all;
22import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010023import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020024import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010025
26import from MobileL3_CommonIE_Types all;
27import from MobileL3_GMM_SM_Types all;
28import from MobileL3_Types all;
29import from L3_Templates all;
30import from L3_Common all;
31
32import from GSUP_Emulation all;
33import from GSUP_Types all;
34import from IPA_Emulation all;
35
Harald Welte26fbb6e2019-04-14 17:32:46 +020036import from RAN_Adapter all;
37import from RAN_Emulation all;
38import from RANAP_Templates all;
39import from RANAP_PDU_Descriptions all;
40import from RANAP_IEs all;
41
Harald Welteeded9ad2018-02-17 20:57:34 +010042import from GTP_Emulation all;
43import from GTP_Templates all;
44import from GTP_CodecPort all;
45import from GTPC_Types all;
46import from GTPU_Types all;
47
Harald Weltea2526a82018-02-18 19:03:36 +010048import from LLC_Types all;
49import from LLC_Templates all;
50
51import from SNDCP_Types all;
52
Harald Weltebd194722018-02-16 22:11:08 +010053import from TELNETasp_PortType all;
54import from Osmocom_VTY_Functions all;
55
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010056import from GSM_RR_Types all;
57
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020058import from MobileL3_MM_Types all;
59
Harald Welteeded9ad2018-02-17 20:57:34 +010060
Harald Welte5ac31492018-02-15 20:39:13 +010061modulepar {
62 /* IP/port on which we run our internal GSUP/HLR emulation */
63 charstring mp_hlr_ip := "127.0.0.1";
64 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010065 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020066 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020067
Alexander Couzensf3c1b412018-08-24 00:42:51 +020068 NSConfigurations mp_nsconfig := {
69 {
70 local_udp_port := 21010,
71 local_ip := "127.0.0.1",
72 remote_udp_port := 23000,
73 remote_ip := "127.0.0.1",
74 nsvci := 97,
Harald Welte5e514fa2018-07-05 00:01:45 +020075 nsei := 96,
76 role_sgsn := false,
77 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020078 },
79 {
80 local_udp_port := 21011,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1",
84 nsvci := 98,
Harald Welte5e514fa2018-07-05 00:01:45 +020085 nsei := 97,
86 role_sgsn := false,
87 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020088 },
89 {
90 local_udp_port := 21012,
91 local_ip := "127.0.0.1",
92 remote_udp_port := 23000,
93 remote_ip := "127.0.0.1",
94 nsvci := 99,
Harald Welte5e514fa2018-07-05 00:01:45 +020095 nsei := 98,
96 role_sgsn := false,
97 handle_sns := false
Alexander Couzensf3c1b412018-08-24 00:42:51 +020098 }
Alexander Couzens2c12b242018-07-31 00:30:11 +020099 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200100
101 RAN_Configurations mp_ranap_cfg := {
102 {
103 transport := RANAP_TRANSPORT_IuCS,
104 sccp_service_type := "mtp3_itu",
105 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
106 own_pc := 195,
107 own_ssn := 142,
108 peer_pc := 188, /* 0.23.4 */
109 peer_ssn := 142,
110 sio := '83'O,
111 rctx := 2
112 }
113 }
Harald Welte5ac31492018-02-15 20:39:13 +0100114};
115
116type record GbInstance {
117 NS_CT vc_NS,
118 BSSGP_CT vc_BSSGP,
119 BssgpConfig cfg
120};
Harald Welte96a33b02018-02-04 10:36:22 +0100121
Harald Welte2fa771f2019-05-02 20:13:53 +0200122const integer NUM_GB := 3;
123type record length(NUM_GB) of GbInstance GbInstances;
124type record length(NUM_GB) of NSConfiguration NSConfigurations;
125type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200126
Harald Welte26fbb6e2019-04-14 17:32:46 +0200127const integer NUM_RNC := 1;
128type record of RAN_Configuration RAN_Configurations;
129
Harald Welte96a33b02018-02-04 10:36:22 +0100130type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200131 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200132 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200133 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100134
Harald Welte5ac31492018-02-15 20:39:13 +0100135 var GSUP_Emulation_CT vc_GSUP;
136 var IPA_Emulation_CT vc_GSUP_IPA;
137 /* only to get events from IPA underneath GSUP */
138 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100139
Harald Welteeded9ad2018-02-17 20:57:34 +0100140 var GTP_Emulation_CT vc_GTP;
141
Harald Weltebd194722018-02-16 22:11:08 +0100142 port TELNETasp_PT SGSNVTY;
143
Harald Welte96a33b02018-02-04 10:36:22 +0100144 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200145 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100146};
147
Harald Welte26fbb6e2019-04-14 17:32:46 +0200148type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100149 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100150 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200151 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100152}
153
154type record SGSN_ConnHdlrNetworkPars {
155 boolean expect_ptmsi,
156 boolean expect_auth,
157 boolean expect_ciph
158};
159
160type record BSSGP_ConnHdlrPars {
161 /* IMEI of the simulated ME */
162 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200163 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100164 hexstring imsi,
165 /* MSISDN of the simulated MS (probably unused) */
166 hexstring msisdn,
167 /* P-TMSI allocated to the simulated MS */
168 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100169 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100170 /* TLLI of the simulated MS */
171 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100172 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100173 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200174 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200175 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
176 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100177 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100178 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200179 float t_guard,
180 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200181 SCCP_PAR_Address sccp_addr_local optional,
182 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100183};
184
Alexander Couzens89508702018-07-31 04:16:10 +0200185private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200186 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200187 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
188
189 var RoutingAreaIdentificationV ret := {
190 mccDigit1 := mcc_mnc[0],
191 mccDigit2 := mcc_mnc[1],
192 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200193 mncDigit3 := mcc_mnc[3],
194 mncDigit1 := mcc_mnc[4],
195 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200196 lac := int2oct(cell_id.ra_id.lai.lac, 16),
197 rac := int2oct(cell_id.ra_id.rac, 8)
198 }
199 return ret;
200};
201
Alexander Couzens51114d12018-07-31 18:41:56 +0200202private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
203 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
204 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100205 /* connect lower end of BSSGP emulation with NS upper port */
206 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
207 /* connect lower end of NS emulation to NS codec port (on top of IPL4) */
208 map(gb.vc_NS:NSCP, system:NS_CODEC_PORT);
209
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200210 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5ac31492018-02-15 20:39:13 +0100211 gb.vc_BSSGP.start(BssgpStart(gb.cfg));
212}
213
214private function f_init_gsup(charstring id) runs on test_CT {
215 id := id & "-GSUP";
216 var GsupOps ops := {
217 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
218 };
219
220 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
221 vc_GSUP := GSUP_Emulation_CT.create(id);
222
223 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
224 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
225 /* we use this hack to get events like ASP_IPA_EVENT_UP */
226 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
227
228 vc_GSUP.start(GSUP_Emulation.main(ops, id));
229 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
230
231 /* wait for incoming connection to GSUP port before proceeding */
232 timer T := 10.0;
233 T.start;
234 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700235 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100236 [] T.timeout {
237 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200238 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100239 }
240 }
241}
242
Harald Welteeded9ad2018-02-17 20:57:34 +0100243private function f_init_gtp(charstring id) runs on test_CT {
244 id := id & "-GTP";
245
246 var GtpEmulationCfg gtp_cfg := {
247 gtpc_bind_ip := mp_ggsn_ip,
248 gtpc_bind_port := GTP1C_PORT,
249 gtpu_bind_ip := mp_ggsn_ip,
250 gtpu_bind_port := GTP1U_PORT,
251 sgsn_role := false
252 };
253
254 vc_GTP := GTP_Emulation_CT.create(id);
255 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
256}
257
Harald Weltebd194722018-02-16 22:11:08 +0100258private function f_init_vty() runs on test_CT {
259 map(self:SGSNVTY, system:SGSNVTY);
260 f_vty_set_prompts(SGSNVTY);
261 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200262 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100263 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
264}
265
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200266private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
267 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200268 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200269 } else {
270 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
271 }
272}
273
Harald Weltebd194722018-02-16 22:11:08 +0100274
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200275/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
276function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200277 var integer i;
278
Harald Welte96a33b02018-02-04 10:36:22 +0100279 if (g_initialized == true) {
280 return;
281 }
282 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100283 g_gb[0].cfg := {
284 nsei := 96,
285 bvci := 196,
286 cell_id := {
287 ra_id := {
288 lai := {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100289 mcc_mnc := mcc_mnc, lac := 13135},
Harald Welte5ac31492018-02-15 20:39:13 +0100290 rac := 0
291 },
292 cell_id := 20960
293 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200294 sgsn_role := false,
295 depth := BSSGP_DECODE_DEPTH_L3
Harald Welte5ac31492018-02-15 20:39:13 +0100296 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200297 g_gb[1].cfg := {
298 nsei := 97,
299 bvci := 210,
300 cell_id := {
301 ra_id := {
302 lai := {
303 mcc_mnc := mcc_mnc, lac := 13200},
304 rac := 0
305 },
306 cell_id := 20961
307 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200308 sgsn_role := false,
309 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200310 };
311 g_gb[2].cfg := {
312 nsei := 98,
313 bvci := 220,
314 cell_id := {
315 ra_id := {
316 lai := {
317 mcc_mnc := mcc_mnc, lac := 13300},
318 rac := 0
319 },
320 cell_id := 20962
321 },
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200322 sgsn_role := false,
323 depth := BSSGP_DECODE_DEPTH_L3
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200324 };
Harald Welte96a33b02018-02-04 10:36:22 +0100325
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200326 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200327 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
328 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
329 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200330
Alexander Couzens1552e792019-07-23 20:38:39 +0200331 if (g_ranap_enable) {
332 for (i := 0; i < NUM_RNC; i := i+1) {
333 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
334 f_ran_adapter_start(g_ranap[i]);
335 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200336 }
Harald Welte5ac31492018-02-15 20:39:13 +0100337 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100338 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200339 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100340}
Harald Welte96a33b02018-02-04 10:36:22 +0100341
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200342function f_cleanup() runs on test_CT {
343 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200344 if (g_ranap_enable) {
345 for (i := 0; i < NUM_RNC; i := i+1) {
346 f_ran_adapter_cleanup(g_ranap[i]);
347 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200348 }
349 self.stop;
350}
351
Harald Welte26fbb6e2019-04-14 17:32:46 +0200352private function RncUnitdataCallback(RANAP_PDU ranap)
353runs on RAN_Emulation_CT return template RANAP_PDU {
354 var template RANAP_PDU resp := omit;
355
356 log ("RANAP_RncUnitDataCallback");
357 /* answer all RESET with RESET ACK */
358 if (match(ranap, tr_RANAP_Reset)) {
359 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
360 var CN_DomainIndicator dom;
361 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
362 resp := ts_RANAP_ResetAck(dom);
363 }
364 return resp;
365}
366
367const RanOps RNC_RanOps := {
368 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
369 ranap_unitdata_cb := refers(RncUnitdataCallback),
370 ps_domain := true,
371 decode_dtap := true,
372 role_ms := true,
373 protocol := RAN_PROTOCOL_RANAP,
374 transport := RANAP_TRANSPORT_IuCS,
375 use_osmux := false,
376 sccp_addr_local := omit,
377 sccp_addr_peer := omit
378};
379
Harald Welte5ac31492018-02-15 20:39:13 +0100380type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
381
382/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200383function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100384 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100385runs on test_CT return BSSGP_ConnHdlr {
386 var BSSGP_ConnHdlr vc_conn;
387 var SGSN_ConnHdlrNetworkPars net_pars := {
388 expect_ptmsi := true,
389 expect_auth := true,
390 expect_ciph := false
391 };
392 var BSSGP_ConnHdlrPars pars := {
393 imei := f_gen_imei(imsi_suffix),
394 imsi := f_gen_imsi(imsi_suffix),
395 msisdn := f_gen_msisdn(imsi_suffix),
396 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100397 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100398 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100399 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100400 ra := omit,
Alexander Couzens51114d12018-07-31 18:41:56 +0200401 bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200402 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100403 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100404 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200405 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200406 sccp_addr_local := omit,
407 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100408 };
409
Alexander Couzens1552e792019-07-23 20:38:39 +0200410 if (g_ranap_enable) {
411 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
412 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
413 }
414
Harald Welte5ac31492018-02-15 20:39:13 +0100415 vc_conn := BSSGP_ConnHdlr.create(id);
Alexander Couzens51114d12018-07-31 18:41:56 +0200416 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200417 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200418 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
419 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200420 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200421 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
422 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
Harald Welte15fbaa42020-06-17 16:37:10 +0200423 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
Alexander Couzens51114d12018-07-31 18:41:56 +0200424 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100425
Harald Welte26fbb6e2019-04-14 17:32:46 +0200426 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200427 if (g_ranap_enable) {
428 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
429 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
430 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200431
Harald Welte5ac31492018-02-15 20:39:13 +0100432 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
433 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
434
Harald Welteeded9ad2018-02-17 20:57:34 +0100435 connect(vc_conn:GTP, vc_GTP:CLIENT);
436 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
437
Harald Welte5ac31492018-02-15 20:39:13 +0100438 vc_conn.start(f_handler_init(fn, id, pars));
439 return vc_conn;
440}
441
Harald Welte62e29582018-02-16 21:17:11 +0100442private altstep as_Tguard() runs on BSSGP_ConnHdlr {
443 [] g_Tguard.timeout {
444 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200445 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100446 }
447}
448
Harald Welte5ac31492018-02-15 20:39:13 +0100449/* first function called in every ConnHdlr */
450private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
451runs on BSSGP_ConnHdlr {
452 /* do some common stuff like setting up g_pars */
453 g_pars := pars;
454
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200455 llc := f_llc_create(false);
456
Harald Welte5ac31492018-02-15 20:39:13 +0100457 /* register with BSSGP core */
Alexander Couzens51114d12018-07-31 18:41:56 +0200458 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welte5ac31492018-02-15 20:39:13 +0100459 /* tell GSUP dispatcher to send this IMSI to us */
460 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100461 /* tell GTP dispatcher to send this IMSI to us */
462 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100463
Harald Welte62e29582018-02-16 21:17:11 +0100464 g_Tguard.start(pars.t_guard);
465 activate(as_Tguard());
466
Harald Welte5ac31492018-02-15 20:39:13 +0100467 /* call the user-supplied test case function */
468 fn.apply(id);
469 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100470}
471
472/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100473 * Detach without Attach
474 * SM procedures without attach / RAU
475 * ATTACH / RAU
476 ** with / without authentication
477 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100478 * re-transmissions of LLC frames
479 * PDP Context activation
480 ** with different GGSN config in SGSN VTY
481 ** with different PDP context type (v4/v6/v46)
482 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100483 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100484 */
485
486testcase TC_wait_ns_up() runs on test_CT {
487 f_init();
488 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200489 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100490}
491
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200492friend function is_gb(integer ran_index) return boolean {
493 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200494}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200495friend function is_iu(integer ran_index) return boolean {
496 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200497}
498
Alexander Couzens0507ec32019-09-15 22:41:22 +0200499function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200500 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200501 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 +0200502}
503
Alexander Couzens0507ec32019-09-15 22:41:22 +0200504private 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 +0200505 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
506 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
507 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200508 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200509}
510
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200511/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
512function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
513 log("Sending InitialUE: ", l3_mo);
514 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
515 var RANAP_PDU ranap;
516 var LAI lai := {
517 pLMNidentity := '62F224'O,
518 lAC := '1234'O,
519 iE_Extensions := omit
520 };
521 var SAI sai := {
522 pLMNidentity := lai.pLMNidentity,
523 lAC := lai.lAC,
524 sAC := '0000'O, /* FIXME */
525 iE_Extensions := omit
526 };
527 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
528 var GlobalRNC_ID grnc_id := {
529 pLMNidentity := lai.pLMNidentity,
530 rNC_ID := 2342 /* FIXME */
531 };
532
533 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
534 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
535 alt {
536 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
537 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
538 setverdict(fail, "DISC.ind from SCCP");
539 mtc.stop;
540 }
541 }
542}
543
544/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200545function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
546 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200547 if (g_pars.rnc_send_initial_ue) {
548 g_pars.rnc_send_initial_ue := false;
549 f_send_l3_initial_ue(l3_mo);
550 } else {
551 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
552 }
553 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200554 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200555 }
556}
557
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200558altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700559 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200560 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100561 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200562 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100563 repeat;
564 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200565 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200566 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200567 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200568 repeat;
569 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200570 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100571 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200572 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200573 repeat;
574 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200575 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200576 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200577 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100578 repeat;
579 }
580}
Harald Welte96a33b02018-02-04 10:36:22 +0100581
Harald Welteca362462019-05-02 20:11:21 +0200582/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200583function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200584runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200585 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200586 var PDU_L3_SGSN_MS l3_mt;
587 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200588 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
589 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200590 l3_mt := mt.dtap;
591 }
Harald Welteca362462019-05-02 20:11:21 +0200592 }
593 return l3_mt;
594}
595
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200596/* perform GMM authentication (if expected).
597 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
598 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200599function 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 +0100600 var PDU_L3_MS_SGSN l3_mo;
601 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200602 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100603 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200604 var GSUP_IE auth_tuple;
605 var template AuthenticationParameterAUTNTLV autn;
606
607 if (umts_aka_challenge) {
608 g_pars.vec := f_gen_auth_vec_3g();
609 autn := {
610 elementIdentifier := '28'O,
611 lengthIndicator := lengthof(g_pars.vec.autn),
612 autnValue := g_pars.vec.autn
613 };
614
615 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
616 g_pars.vec.sres,
617 g_pars.vec.kc,
618 g_pars.vec.ik,
619 g_pars.vec.ck,
620 g_pars.vec.autn,
621 g_pars.vec.res));
622 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
623 } else {
624 g_pars.vec := f_gen_auth_vec_2g();
625 autn := omit;
626 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
627 g_pars.vec.sres,
628 g_pars.vec.kc));
629 log("GSUP sends only 2G auth tuple", auth_tuple);
630 }
Harald Welteca362462019-05-02 20:11:21 +0200631
Harald Welte5ac31492018-02-15 20:39:13 +0100632 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
633 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200634
635 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
636 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200637 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100638 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200639 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
640
641 if (umts_aka_challenge and not force_gsm_sres) {
642 /* set UMTS response instead */
643 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
644 valueField := substr(g_pars.vec.res, 0, 4)
645 };
646 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
647 elementIdentifier := '21'O,
648 lengthIndicator := lengthof(g_pars.vec.res) - 4,
649 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
650 };
651 }
652
653 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100654 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
655 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
656 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
657 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
658 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200659 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200660
661 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200663 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
664 key_sts := ?)) {
665 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
666 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200667 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200668 }
669 }
Harald Welte76dee092018-02-16 22:12:59 +0100670 } else {
671 /* wait for identity procedure */
672 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100673 }
Harald Welte76dee092018-02-16 22:12:59 +0100674
Harald Welte5ac31492018-02-15 20:39:13 +0100675 deactivate(di);
676}
677
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200678function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100679 g_pars.p_tmsi := p_tmsi;
680 /* update TLLI */
681 g_pars.tlli_old := g_pars.tlli;
682 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100683 if (is_gb(ran_index)) {
684 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
685 }
Harald Weltef70997d2018-02-17 10:11:19 +0100686}
687
Harald Welte04683d02018-02-16 22:43:45 +0100688function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
689 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100690 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200691 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100692 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200693 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200694 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100695 }
Harald Welte04683d02018-02-16 22:43:45 +0100696 g_pars.ra := aa.routingAreaIdentification;
697 if (ispresent(aa.allocatedPTMSI)) {
698 if (not g_pars.net.expect_ptmsi) {
699 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200700 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100701 }
Harald Weltef70997d2018-02-17 10:11:19 +0100702 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100703 }
704 if (ispresent(aa.msIdentity)) {
705 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200706 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100707 }
708 /* P-TMSI.sig */
709 if (ispresent(aa.ptmsiSignature)) {
710 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
711 }
712 /* updateTimer */
713 // aa.readyTimer
714 /* T3302, T3319, T3323, T3312_ext, T3324 */
715}
716
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200717function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100718 /* mandatory IE */
719 g_pars.ra := ra.routingAreaId;
720 if (ispresent(ra.allocatedPTMSI)) {
721 if (not g_pars.net.expect_ptmsi) {
722 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200723 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100724 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200725 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100726 }
727 if (ispresent(ra.msIdentity)) {
728 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200729 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100730 }
731 /* P-TMSI.sig */
732 if (ispresent(ra.ptmsiSignature)) {
733 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
734 }
735 /* updateTimer */
736 // aa.readyTimer
737 /* T3302, T3319, T3323, T3312_ext, T3324 */
738}
739
740
Harald Welte5a4fa042018-02-16 20:59:21 +0100741function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
742 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
743}
744
Harald Welte23178c52018-02-17 09:36:33 +0100745/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700746private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100747 if (ispresent(g_pars.p_tmsi)) {
748 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
749 } else {
750 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
751 }
752}
753
Harald Welte311ec272018-02-17 09:40:03 +0100754private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100755 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100756 /* Expect MSC to perform LU with HLR */
757 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100758 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
759 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
760 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100761 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
762 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
763}
764
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200765friend 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 +0100766 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200767 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 +0200768 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100769
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200770 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
771 * 3G auth vectors */
772 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
773 /* The thing is, if the solSACapability is 'omit', then the
774 * revisionLevelIndicatior is at the wrong place! */
775 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
776
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200777 f_send_l3(attach_req, ran_index);
778 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200779 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100780 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100781
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200782 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200783 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
784
Harald Welte04683d02018-02-16 22:43:45 +0100785 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200786 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200787
788 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200789 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200790 as_iu_release_compl_disc();
791 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200792
793 /* Race condition
794 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
795 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
796 * arrived before it. This results in a test case failure.
797 * Delay execution by 50 ms
798 */
799 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200800}
801
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200802friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
803 timer T := 5.0;
804 var PDU_BSSGP rx_pdu;
805 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
806 T.start;
807 alt {
808 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
809 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
810 }
811 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
812 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
813 mtc.stop;
814 }
815 [] T.timeout {
816 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
817 mtc.stop;
818 }
819 }
820 return '00'O;
821}
822
823friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
824 timer T := 5.0;
825 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
826 T.start;
827 alt {
828 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
829 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
830?)) {
831 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
832 mtc.stop;
833 }
834 [] T.timeout {
835 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
836 mtc.stop;
837 }
838 }
839}
840
841
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200842private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
843 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100844 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100845}
846
847testcase TC_attach() runs on test_CT {
848 var BSSGP_ConnHdlr vc_conn;
849 f_init();
850 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200851 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100852 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200853 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100854}
855
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100856testcase TC_attach_mnc3() runs on test_CT {
857 var BSSGP_ConnHdlr vc_conn;
858 f_init('023042'H);
859 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200860 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100861 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200862 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100863}
864
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200865private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
866 f_gmm_attach(true, false);
867 setverdict(pass);
868}
869testcase TC_attach_umts_aka_umts_res() runs on test_CT {
870 var BSSGP_ConnHdlr vc_conn;
871 f_init();
872 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200873 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200874 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200875 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200876}
877
878private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
879 f_gmm_attach(true, true);
880 setverdict(pass);
881}
882testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
883 var BSSGP_ConnHdlr vc_conn;
884 f_init();
885 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200886 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200887 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200888 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200889}
890
Harald Welte5b7c8122018-02-16 21:48:17 +0100891/* MS never responds to ID REQ, expect ATTACH REJECT */
892private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100893 var RoutingAreaIdentificationV old_ra := f_random_RAI();
894
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200895 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100896 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200897 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100898 /* don't send ID Response */
899 repeat;
900 }
Harald Welte955aa942019-05-03 01:29:29 +0200901 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100902 setverdict(pass);
903 }
Harald Welte955aa942019-05-03 01:29:29 +0200904 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100905 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200906 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100907 }
908 }
909}
910testcase TC_attach_auth_id_timeout() runs on test_CT {
911 var BSSGP_ConnHdlr vc_conn;
912 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200913 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 +0100914 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200915 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100916}
917
918/* HLR never responds to SAI REQ, expect ATTACH REJECT */
919private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100920 var RoutingAreaIdentificationV old_ra := f_random_RAI();
921
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200922 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100923 alt {
924 [] as_mm_identity();
925 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
926 }
927 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200928 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100929 setverdict(pass);
930}
931testcase TC_attach_auth_sai_timeout() runs on test_CT {
932 var BSSGP_ConnHdlr vc_conn;
933 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200934 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100935 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200936 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100937}
938
Harald Weltefe253882018-02-17 09:25:00 +0100939/* HLR rejects SAI, expect ATTACH REJECT */
940private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +0100941 var RoutingAreaIdentificationV old_ra := f_random_RAI();
942
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200943 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +0100944 alt {
945 [] as_mm_identity();
946 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
947 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
948 }
949 }
Harald Welte955aa942019-05-03 01:29:29 +0200950 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +0100951 setverdict(pass);
952}
953testcase TC_attach_auth_sai_reject() runs on test_CT {
954 var BSSGP_ConnHdlr vc_conn;
955 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200956 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +0100957 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200958 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +0100959}
960
Harald Welte5b7c8122018-02-16 21:48:17 +0100961/* HLR never responds to UL REQ, expect ATTACH REJECT */
962private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200963 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +0100964 var RoutingAreaIdentificationV old_ra := f_random_RAI();
965
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200966 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100967 f_gmm_auth();
968 /* Expect MSC to perform LU with HLR */
969 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
970 /* Never follow-up with ISD_REQ or UL_RES */
971 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200972 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100973 setverdict(pass);
974 }
Harald Welte955aa942019-05-03 01:29:29 +0200975 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
976 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +0100977 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +0200978 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100979 }
980 }
981}
982testcase TC_attach_gsup_lu_timeout() runs on test_CT {
983 var BSSGP_ConnHdlr vc_conn;
984 f_init();
985 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200986 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +0100987 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200988 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100989}
990
Harald Welteb7c14e92018-02-17 09:29:16 +0100991/* HLR rejects UL REQ, expect ATTACH REJECT */
992private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +0200993 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +0100994 var RoutingAreaIdentificationV old_ra := f_random_RAI();
995
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200996 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +0100997 f_gmm_auth();
998 /* Expect MSC to perform LU with HLR */
999 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1000 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1001 }
1002 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001003 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001004 setverdict(pass);
1005 }
Harald Welte955aa942019-05-03 01:29:29 +02001006 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1007 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001008 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001009 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001010 }
1011 }
1012}
1013testcase TC_attach_gsup_lu_reject() runs on test_CT {
1014 var BSSGP_ConnHdlr vc_conn;
1015 f_init();
1016 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001017 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001018 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001019 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001020}
1021
1022
Harald Welte3823e2e2018-02-16 21:53:48 +01001023/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1024private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001025 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001026 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1027
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001028 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001029 f_gmm_auth();
1030 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001031 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001032
Harald Welte955aa942019-05-03 01:29:29 +02001033 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1034 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001035 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001036 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001037 setverdict(pass);
1038}
Harald Welte3823e2e2018-02-16 21:53:48 +01001039testcase TC_attach_combined() runs on test_CT {
1040 var BSSGP_ConnHdlr vc_conn;
1041 f_init();
1042 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001043 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001044 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001045 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001046}
1047
Harald Welte76dee092018-02-16 22:12:59 +01001048/* Attempt of GPRS ATTACH in 'accept all' mode */
1049private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001050 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001051 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1052
1053 g_pars.net.expect_auth := false;
1054
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001055 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001056 f_gmm_auth();
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 Welte04683d02018-02-16 22:43:45 +01001059 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001060 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001061 setverdict(pass);
1062}
1063testcase TC_attach_accept_all() runs on test_CT {
1064 var BSSGP_ConnHdlr vc_conn;
1065 f_init();
1066 f_sleep(1.0);
1067 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001068 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001069 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001070 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001071}
Harald Welte5b7c8122018-02-16 21:48:17 +01001072
Harald Welteb2124b22018-02-16 22:26:56 +01001073/* Attempt of GPRS ATTACH in 'accept all' mode */
1074private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001075 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1076
1077 /* Simulate a foreign IMSI */
1078 g_pars.imsi := '001010123456789'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02001079 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Harald Welteb2124b22018-02-16 22:26:56 +01001080
1081 g_pars.net.expect_auth := false;
1082
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001083 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001084 alt {
1085 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001086 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001087 setverdict(pass);
1088 }
Harald Welte955aa942019-05-03 01:29:29 +02001089 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001090 setverdict(pass);
1091 }
Harald Welte955aa942019-05-03 01:29:29 +02001092 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001093 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001094 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001095 }
Harald Welteb2124b22018-02-16 22:26:56 +01001096 }
1097}
1098testcase TC_attach_closed() runs on test_CT {
1099 var BSSGP_ConnHdlr vc_conn;
1100 f_init();
1101 f_sleep(1.0);
1102 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1103 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001104 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001105 vc_conn.done;
1106 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001107 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001108 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001109 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001110}
1111
Harald Welte04683d02018-02-16 22:43:45 +01001112/* Routing Area Update from Unknown TLLI -> REJECT */
1113private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001114 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1115
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001116 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 +01001117 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001118 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001119 setverdict(pass);
1120 }
1121 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001122 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001123 }
1124}
1125testcase TC_rau_unknown() runs on test_CT {
1126 var BSSGP_ConnHdlr vc_conn;
1127 f_init();
1128 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001129 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001130 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001131 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001132}
1133
Harald Welte91636de2018-02-17 10:16:14 +01001134private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001135 /* first perform regular attach */
1136 f_TC_attach(id);
1137
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001138 f_routing_area_update(g_pars.ra);
1139
Harald Welte91636de2018-02-17 10:16:14 +01001140}
1141testcase TC_attach_rau() runs on test_CT {
1142 var BSSGP_ConnHdlr vc_conn;
1143 f_init();
1144 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001145 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001146 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001147 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001148}
Harald Welte04683d02018-02-16 22:43:45 +01001149
Harald Welte6abb9fe2018-02-17 15:24:48 +01001150/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001151function 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 +02001152 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001153 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001154 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001155 if (expect_purge) {
1156 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1157 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1158 }
1159 T.start;
1160 alt {
1161 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1162 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001163 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001164 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001165 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001166 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001167 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001168 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001169 /* TODO: check if any PDP contexts are deactivated on network side? */
1170 }
1171 [power_off] T.timeout {
1172 setverdict(pass);
1173 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001174 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001175 g_pars.ra := omit;
1176 setverdict(pass);
1177 /* TODO: check if any PDP contexts are deactivated on network side? */
1178 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001179 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001180 if (power_off) {
1181 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1182 } else {
1183 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1184 }
1185 mtc.stop;
1186 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001187 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001188 }
1189}
1190
1191/* IMSI DETACH (non-power-off) for unknown TLLI */
1192private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1193 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1194}
1195testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1196 var BSSGP_ConnHdlr vc_conn;
1197 f_init();
1198 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001199 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001200 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001201 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001202}
1203
1204/* IMSI DETACH (power-off) for unknown TLLI */
1205private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1206 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1207}
1208testcase TC_detach_unknown_poweroff() runs on test_CT {
1209 var BSSGP_ConnHdlr vc_conn;
1210 f_init();
1211 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001212 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001213 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001214 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001215}
1216
1217/* IMSI DETACH (non-power-off) for known TLLI */
1218private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1219 /* first perform regular attach */
1220 f_TC_attach(id);
1221
1222 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1223}
1224testcase TC_detach_nopoweroff() runs on test_CT {
1225 var BSSGP_ConnHdlr vc_conn;
1226 f_init();
1227 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001228 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001229 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001230 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001231}
1232
1233/* IMSI DETACH (power-off) for known TLLI */
1234private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1235 /* first perform regular attach */
1236 f_TC_attach(id);
1237
1238 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1239}
1240testcase TC_detach_poweroff() runs on test_CT {
1241 var BSSGP_ConnHdlr vc_conn;
1242 f_init();
1243 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001244 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001245 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001246 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001247}
1248
Harald Welteeded9ad2018-02-17 20:57:34 +01001249type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001250 BIT3 tid, /* L3 Transaction ID */
1251 BIT4 nsapi, /* SNDCP NSAPI */
1252 BIT4 sapi, /* LLC SAPI */
1253 QoSV qos, /* QoS parameters */
1254 PDPAddressV addr, /* IP address */
1255 octetstring apn optional, /* APN name */
1256 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1257 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001258 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001259 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001260
Harald Welte822f9102018-02-18 20:39:06 +01001261 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1262 OCT4 ggsn_tei_u, /* GGSN TEI User */
1263 octetstring ggsn_ip_c, /* GGSN IP Control */
1264 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001265 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001266
Harald Welte822f9102018-02-18 20:39:06 +01001267 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1268 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1269 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1270 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001271};
1272
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001273
1274private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1275 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1276 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1277 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1278 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1279 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1280 f_gtp_register_teid(apars.ggsn_tei_c);
1281 f_gtp_register_teid(apars.ggsn_tei_u);
1282}
1283
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001284function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001285runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001286 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1287 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001288 var template Recovery_gtpc recovery := omit;
1289
1290 if (send_recovery) {
1291 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1292 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001293
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001294 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 +02001295 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001296 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1297 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1298 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1299 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1300 apars.sgsn_tei_c, apars.gtp_resp_cause,
1301 apars.ggsn_tei_c, apars.ggsn_tei_u,
1302 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001303 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1304 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001305 }
1306 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001307 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001308 setverdict(pass);
1309 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001310 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001311 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001312 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001313 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001314 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001315 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001316 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001317 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001318 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001319 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1320 mtc.stop;
1321 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001322 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001323 setverdict(pass);
1324 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001325 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001326 }
1327}
1328
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001329function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001330runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001331 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1332 var Gtp1cUnitdata g_ud;
1333
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001334 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001335 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1336 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001337 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001338 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1339 }
1340 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001341 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001342 setverdict(pass);
1343 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001344 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001345 }
1346}
1347
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001348function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001349runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001350 var Gtp1cUnitdata g_ud;
1351 var integer seq_nr := 23;
1352 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1353
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001354 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001355 if (error_ind) {
1356 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1357 } else {
1358 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1359 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001360
1361 timer T := 5.0;
1362 T.start;
1363
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001364 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001365 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1366 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001367 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001368 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1369 repeat;
1370 }
1371 [] T.timeout {
1372 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1373 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001374 }
1375}
1376
Harald Welte6f203162018-02-18 22:04:55 +01001377
Harald Welteeded9ad2018-02-17 20:57:34 +01001378/* Table 10.5.156/3GPP TS 24.008 */
1379template (value) QoSV t_QosDefault := {
1380 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1381 delayClass := '100'B, /* best effort */
1382 spare1 := '00'B,
1383 precedenceClass := '010'B, /* normal */
1384 spare2 := '0'B,
1385 peakThroughput := '0000'B, /* subscribed */
1386 meanThroughput := '00000'B, /* subscribed */
1387 spare3 := '000'B,
1388 deliverErroneusSDU := omit,
1389 deliveryOrder := omit,
1390 trafficClass := omit,
1391 maxSDUSize := omit,
1392 maxBitrateUplink := omit,
1393 maxBitrateDownlink := omit,
1394 sduErrorRatio := omit,
1395 residualBER := omit,
1396 trafficHandlingPriority := omit,
1397 transferDelay := omit,
1398 guaranteedBitRateUplink := omit,
1399 guaranteedBitRateDownlink := omit,
1400 sourceStatisticsDescriptor := omit,
1401 signallingIndication := omit,
1402 spare4 := omit,
1403 maxBitrateDownlinkExt := omit,
1404 guaranteedBitRateDownlinkExt := omit,
1405 maxBitrateUplinkExt := omit,
1406 guaranteedBitRateUplinkExt := omit,
1407 maxBitrateDownlinkExt2 := omit,
1408 guaranteedBitRateDownlinkExt2 := omit,
1409 maxBitrateUplinkExt2 := omit,
1410 guaranteedBitRateUplinkExt2 := omit
1411}
1412
1413/* 10.5.6.4 / 3GPP TS 24.008 */
1414template (value) PDPAddressV t_AddrIPv4dyn := {
1415 pdpTypeOrg := '0001'B, /* IETF */
1416 spare := '0000'B,
1417 pdpTypeNum := '21'O, /* IPv4 */
1418 addressInfo := omit
1419}
1420template (value) PDPAddressV t_AddrIPv6dyn := {
1421 pdpTypeOrg := '0001'B, /* IETF */
1422 spare := '0000'B,
1423 pdpTypeNum := '53'O, /* IPv6 */
1424 addressInfo := omit
1425}
1426
Harald Welte37692d82018-02-18 15:21:34 +01001427template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001428 tid := '000'B,
1429 nsapi := '0101'B, /* < 5 are reserved */
1430 sapi := '0011'B, /* 3/5/9/11 */
1431 qos := t_QosDefault,
1432 addr := t_AddrIPv4dyn,
1433 apn := omit,
1434 pco := omit,
1435 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001436 gtp_resp_cause := int2oct(128, 1),
1437 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001438
1439 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001440 ggsn_tei_c := f_rnd_octstring(4),
1441 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001442 ggsn_ip_c := f_inet_addr(ggsn_ip),
1443 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001444 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001445
Harald Welteeded9ad2018-02-17 20:57:34 +01001446 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001447 sgsn_tei_u := omit,
1448 sgsn_ip_c := omit,
1449 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001450}
1451
Harald Welte37692d82018-02-18 15:21:34 +01001452template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1453 connId := 1,
1454 remName := f_inet_ntoa(ip),
1455 remPort := GTP1U_PORT
1456}
1457
1458template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1459 connId := 1,
1460 remName := f_inet_ntoa(ip),
1461 remPort := GTP1C_PORT
1462}
1463
1464private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1465 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1466 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1467}
1468
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001469private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1470 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001471 repeat;
1472 }
1473}
1474
1475template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1476 pDU_SN_UNITDATA := {
1477 nsapi := nsapi,
1478 moreBit := ?,
1479 snPduType := '1'B,
1480 firstSegmentIndicator := ?,
1481 spareBit := ?,
1482 pcomp := ?,
1483 dcomp := ?,
1484 npduNumber := ?,
1485 segmentNumber := ?,
1486 npduNumberContinued := ?,
1487 dataSegmentSnUnitdataPdu := payload
1488 }
1489}
1490
1491/* simple case: single segment, no compression */
1492template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1493 pDU_SN_UNITDATA := {
1494 nsapi := nsapi,
1495 moreBit := '0'B,
1496 snPduType := '1'B,
1497 firstSegmentIndicator := '1'B,
1498 spareBit := '0'B,
1499 pcomp := '0000'B,
1500 dcomp := '0000'B,
1501 npduNumber := '0000'B,
1502 segmentNumber := '0000'B,
1503 npduNumberContinued := '00'O,
1504 dataSegmentSnUnitdataPdu := payload
1505 }
1506}
1507
1508/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001509private 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 +02001510runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001511 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001512 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1513 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001514 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001515 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1516 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001517 [] as_xid(apars, ran_index);
1518 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001519 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1520 [expect_fwd] T.timeout {
1521 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1522 mtc.stop;
1523 }
1524 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1525 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1526 mtc.stop;
1527 }
1528 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001529 }
1530}
1531
Harald Welte64d6b512020-06-17 16:42:00 +02001532/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001533private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001534runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001535 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1536 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1537 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001538 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001539 /* Expect PDU via GTP from SGSN on simulated GGSN */
1540 alt {
1541 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1542 }
1543}
1544
Harald Welteeded9ad2018-02-17 20:57:34 +01001545private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001546 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001547
1548 /* first perform regular attach */
1549 f_TC_attach(id);
1550
1551 f_pdp_ctx_act(apars);
1552}
1553testcase TC_attach_pdp_act() runs on test_CT {
1554 var BSSGP_ConnHdlr vc_conn;
1555 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001556 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001557 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001558 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001559}
Harald Welteb2124b22018-02-16 22:26:56 +01001560
Harald Welte835b15f2018-02-18 14:39:11 +01001561/* PDP Context activation for not-attached subscriber; expect fail */
1562private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001563 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001564 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 +01001565 apars.apn, apars.pco));
1566 alt {
1567 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001568 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001569 setverdict(pass);
1570 }
1571 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1572 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001573 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001574 }
Harald Welte955aa942019-05-03 01:29:29 +02001575 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001576 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001577 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001578 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001579 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001580 }
1581}
1582testcase TC_pdp_act_unattached() runs on test_CT {
1583 var BSSGP_ConnHdlr vc_conn;
1584 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001585 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001586 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001587 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001588}
1589
Harald Welte37692d82018-02-18 15:21:34 +01001590/* ATTACH + PDP CTX ACT + user plane traffic */
1591private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1592 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1593
1594 /* first perform regular attach */
1595 f_TC_attach(id);
1596 /* then activate PDP context */
1597 f_pdp_ctx_act(apars);
1598 /* then transceive a downlink PDU */
1599 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1600 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1601}
1602testcase TC_attach_pdp_act_user() runs on test_CT {
1603 var BSSGP_ConnHdlr vc_conn;
1604 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001605 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001606 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001607 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001608}
1609
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001610/* ATTACH + PDP CTX ACT; reject from GGSN */
1611private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1612 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1613
1614 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1615 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1616
1617 /* first perform regular attach */
1618 f_TC_attach(id);
1619 /* then activate PDP context */
1620 f_pdp_ctx_act(apars);
1621}
1622testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1623 var BSSGP_ConnHdlr vc_conn;
1624 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001625 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001626 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001627 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001628}
Harald Welte835b15f2018-02-18 14:39:11 +01001629
Harald Welte6f203162018-02-18 22:04:55 +01001630/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1631private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1632 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1633
1634 /* first perform regular attach */
1635 f_TC_attach(id);
1636 /* then activate PDP context */
1637 f_pdp_ctx_act(apars);
1638 /* then transceive a downlink PDU */
1639 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1640 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1641
1642 f_pdp_ctx_deact_mo(apars, '00'O);
1643}
1644testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1645 var BSSGP_ConnHdlr vc_conn;
1646 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001647 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 +01001648 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001649 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001650}
1651
Harald Welte57b9b7f2018-02-18 22:28:13 +01001652/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1653private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1654 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1655
1656 /* first perform regular attach */
1657 f_TC_attach(id);
1658 /* then activate PDP context */
1659 f_pdp_ctx_act(apars);
1660 /* then transceive a downlink PDU */
1661 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1662 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1663
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001664 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001665}
1666testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1667 var BSSGP_ConnHdlr vc_conn;
1668 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001669 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 +01001670 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001671 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001672}
1673
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001674/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1675private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1676 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1677 var Gtp1cUnitdata g_ud;
1678 var integer i;
1679 var OCT1 cause_regular_deact := '24'O;
1680
1681 /* first perform regular attach + PDP context act */
1682 f_TC_attach(id);
1683 f_pdp_ctx_act(apars);
1684
1685 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1686 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1687
1688 for (i := 0; i < 2; i := i+1) {
1689 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1690 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1691 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1692 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1693 }
1694 }
1695
1696 alt {
1697 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1698 setverdict(pass);
1699 }
1700 [] as_xid(apars, 0);
1701 }
1702
1703 /* Make sure second DeactPdpAccept is sent: */
1704 timer T := 2.0;
1705 T.start;
1706 alt {
1707 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1708 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1709 }
1710 [] T.timeout {
1711 setverdict(pass);
1712 }
1713 }
1714
1715 setverdict(pass);
1716}
1717testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1718 var BSSGP_ConnHdlr vc_conn;
1719 f_init();
1720 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1721 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001722 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001723}
1724
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001725/* ATTACH + ATTACH (2nd) */
1726private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1727 g_pars.t_guard := 5.0;
1728
1729 /* first perform regular attach */
1730 f_TC_attach(id);
1731
1732 /* second to perform regular attach */
1733 f_TC_attach(id);
1734}
1735
1736
1737testcase TC_attach_second_attempt() runs on test_CT {
1738 var BSSGP_ConnHdlr vc_conn;
1739 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001740 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001741 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001742 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001743}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001744
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001745private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1746 var Gtp1cUnitdata g_ud;
1747 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1748 var integer seq_nr;
1749
1750 /* first perform regular attach */
1751 f_TC_attach(id);
1752 /* then activate PDP context */
1753 f_pdp_ctx_act(apars);
1754
1755 /* Wait to receive first echo request and send initial Restart counter */
1756 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1757 BSSGP[0].clear;
1758 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1759 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1760 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1761 }
1762
1763 /* At some point next echo request not answered will timeout and SGSN
1764 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1765 timer T := 3.0 * 6.0 + 16.0;
1766 T.start;
1767 alt {
1768 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1769 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1770 setverdict(pass);
1771 }
1772 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1773 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1774 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1775 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1776 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1777 repeat;
1778 }
1779 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1780 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1781 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1782 repeat;
1783 }
1784 [] T.timeout {
1785 setverdict(fail, "BSSGP DeactPdpReq not received");
1786 mtc.stop;
1787 }
1788 [] as_xid(apars);
1789 }
1790 T.stop
1791
1792 setverdict(pass);
1793}
1794/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1795testcase TC_attach_echo_timeout() runs on test_CT {
1796 var BSSGP_ConnHdlr vc_conn;
1797 g_use_echo := true;
1798 f_init();
1799 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1800 vc_conn.done;
1801 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001802 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001803}
1804
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001805private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001806 var Gtp1cUnitdata g_ud;
1807 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1808
1809 /* first perform regular attach */
1810 f_TC_attach(id);
1811 /* Activate a pdp context against the GGSN */
1812 f_pdp_ctx_act(apars);
1813 /* Wait to receive first echo request and send initial Restart counter */
1814 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1815 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1816 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1817 }
1818 /* Wait to receive second echo request and send incremented Restart
1819 counter. This will fake a restarted GGSN, and pdp ctx allocated
1820 should be released by SGSN */
1821 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1822 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1823 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1824 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1825 }
1826 var OCT1 cause_network_failure := int2oct(38, 1)
1827 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001828 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001829 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001830 setverdict(pass);
1831 }
1832 [] as_xid(apars);
1833 }
1834 setverdict(pass);
1835}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001836/* ATTACH + trigger Recovery procedure through EchoResp */
1837testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001838 var BSSGP_ConnHdlr vc_conn;
1839 g_use_echo := true
1840 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001841 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 +02001842 vc_conn.done;
1843 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001844 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001845}
1846
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001847private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1848 var Gtp1cUnitdata g_ud;
1849 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1850 var integer seq_nr := 23;
1851 var GtpPeer peer;
1852 /* first perform regular attach */
1853 f_TC_attach(id);
1854
1855 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1856 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1857 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1858 f_pdp_ctx_act(apars, true);
1859
1860 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1861/* received. */
1862 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1863
1864 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1865 would be great to have an active pdp context here before triggering
1866 Recovery, and making sure the the DEACT request is sent by the SGSN.
1867 */
1868
1869 /* Activate a pdp context against the GGSN, send incremented Recovery
1870 IE. This should trigger the recovery path, but still this specific
1871 CTX activation should work. */
1872 apars.exp_rej_cause := omit; /* default value for tests */
1873 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1874 f_pdp_ctx_act(apars, true);
1875
1876 setverdict(pass);
1877}
1878/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1879testcase TC_attach_restart_ctr_create() runs on test_CT {
1880 var BSSGP_ConnHdlr vc_conn;
1881 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001882 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 +02001883 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001884 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001885}
1886
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001887/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1888private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1889 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1890 var integer seq_nr := 23;
1891 var GtpPeer peer;
1892 var integer i;
1893
1894 /* first perform regular attach */
1895 f_TC_attach(id);
1896 /* then activate PDP context */
1897 f_pdp_ctx_act(apars);
1898
Alexander Couzens0e510e62018-07-28 23:06:00 +02001899 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001900 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1901 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1902
1903 for (i := 0; i < 5; i := i+1) {
1904 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001905 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001906 [] as_xid(apars);
1907 }
1908 }
1909
1910 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1911
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001912 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001913 setverdict(pass);
1914}
1915testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1916 var BSSGP_ConnHdlr vc_conn;
1917 f_init();
1918 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001919 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 +02001920 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001921 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001922}
1923
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001924/* ATTACH + PDP CTX ACT dropped + retrans */
1925private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1926 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1927 var Gtp1cUnitdata g_ud_first, g_ud_second;
1928 /* first perform regular attach */
1929 f_TC_attach(id);
1930
1931 /* then activate PDP context on the Gb side */
1932 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1933 apars.apn, apars.pco), 0);
1934
1935 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1936 log("First createPDPContextRequest received, dropping & waiting for retransmission");
1937 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
1938 if (g_ud_first != g_ud_second) {
1939 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
1940 mtc.stop;
1941 }
1942 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
1943 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1944 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
1945 apars.sgsn_tei_c, apars.gtp_resp_cause,
1946 apars.ggsn_tei_c, apars.ggsn_tei_u,
1947 apars.nsapi,
1948 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1949 omit, omit));
1950 }
Harald Welte955aa942019-05-03 01:29:29 +02001951 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001952
1953 /* Now the same with Deact */
1954 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
1955 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
1956 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
1957 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
1958 if (g_ud_first != g_ud_second) {
1959 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
1960 mtc.stop;
1961 }
1962 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
1963 BSSGP[0].clear;
1964 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1965 }
1966 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001967 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001968 setverdict(pass);
1969 }
1970 [] as_xid(apars, 0);
1971 }
1972
1973 setverdict(pass);
1974}
1975testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
1976 var BSSGP_ConnHdlr vc_conn;
1977 f_init();
1978 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
1979 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001980 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001981}
1982
1983/* Test that SGSN GTP response retransmit queue works fine */
1984private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
1985 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1986 var integer seq_nr := 23;
1987 var Gtp1cUnitdata g_ud_first, g_ud_second;
1988 var template Gtp1cUnitdata g_delete_req;
1989 /* first perform regular attach + PDP context act */
1990 f_TC_attach(id);
1991 f_pdp_ctx_act(apars);
1992
1993 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
1994 BSSGP[0].clear;
1995 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1996 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
1997 GTP.send(g_delete_req);
1998 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001999 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002000 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2001 }
2002 [] as_xid(apars, 0);
2003 }
2004 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2005 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2006 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2007 mtc.stop;
2008 }
2009 };
2010
2011 /* Send duplicate DeleteCtxReq */
2012 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2013 GTP.send(g_delete_req);
2014 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2015 if (g_ud_first != g_ud_second) {
2016 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2017 mtc.stop;
2018 }
2019 }
2020
2021 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2022 * is handled differently by SGSN (expect "non-existent" cause) */
2023 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2024 GTP.send(g_delete_req);
2025 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2026 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2027 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2028 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2029 mtc.stop;
2030 }
2031 }
2032
2033 setverdict(pass);
2034}
2035testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2036 var BSSGP_ConnHdlr vc_conn;
2037 f_init();
2038 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2039 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002040 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002041}
2042
Alexander Couzens5e307b42018-05-22 18:12:20 +02002043private function f_TC_hlr_location_cancel_request_update(charstring id) runs on BSSGP_ConnHdlr {
2044 /* MS: perform regular attach */
2045 f_TC_attach(id);
2046
2047 /* HLR: cancel the location request */
2048 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_UPDATE));
2049 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002050
2051 /* ensure no Detach Request got received */
2052 timer T := 5.0;
2053 T.start;
2054 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002055 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002056 T.stop;
2057 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002058 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002059 }
2060 [] T.timeout {
2061 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002062 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002063 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002064 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002065 repeat;
2066 }
2067 }
2068}
2069
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002070/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2071private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2072 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2073
2074 /* first perform regular attach */
2075 f_TC_attach(id);
2076 /* then activate PDP context */
2077 f_pdp_ctx_act(apars);
2078 /* then transceive a downlink PDU */
2079 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2080
2081 /* Send Error indication as response from upload PDU and expect deact towards MS */
2082 f_pdp_ctx_deact_mt(apars, true);
2083}
2084testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2085 var BSSGP_ConnHdlr vc_conn;
2086 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002087 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 +02002088 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002089 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002090}
2091
Alexander Couzens5e307b42018-05-22 18:12:20 +02002092testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2093 /* MS <-> SGSN: GMM Attach
2094 * HLR -> SGSN: Cancel Location Request
2095 * HLR <- SGSN: Cancel Location Ack
2096 */
2097 var BSSGP_ConnHdlr vc_conn;
2098 f_init();
2099 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002100 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002101 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002102 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002103}
2104
2105
Alexander Couzensc87967a2018-05-22 16:09:54 +02002106private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2107 /* MS: perform regular attach */
2108 f_TC_attach(id);
2109
2110 /* HLR: cancel the location request */
2111 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2112 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2113 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2114
2115 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002116 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002117 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002118
2119 setverdict(pass);
2120}
2121
2122testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2123 /* MS <-> SGSN: GMM Attach
2124 * HLR -> SGSN: Cancel Location Request
2125 * HLR <- SGSN: Cancel Location Ack
2126 * MS <- SGSN: Detach Request
2127 * SGSN-> MS: Detach Complete
2128 */
2129 var BSSGP_ConnHdlr vc_conn;
2130 f_init();
2131 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002132 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002133 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002134 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002135}
2136
2137
Alexander Couzens6c47f292018-05-22 17:09:49 +02002138private function f_hlr_location_cancel_request_unknown_subscriber(
2139 charstring id,
2140 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2141
2142 /* HLR: cancel the location request */
2143 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2144
2145 /* cause 2 = IMSI_UNKNOWN */
2146 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2147
2148 setverdict(pass);
2149}
2150
2151private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002152 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002153}
2154
2155testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2156 /* HLR -> SGSN: Cancel Location Request
2157 * HLR <- SGSN: Cancel Location Error
2158 */
2159
2160 var BSSGP_ConnHdlr vc_conn;
2161 f_init();
2162 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002163 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 +02002164 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002165 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002166}
2167
2168private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002169 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002170}
2171
2172testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2173 /* HLR -> SGSN: Cancel Location Request
2174 * HLR <- SGSN: Cancel Location Error
2175 */
2176
2177 var BSSGP_ConnHdlr vc_conn;
2178 f_init();
2179 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002180 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 +02002181 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002182 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002183}
2184
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002185private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2186 f_TC_attach(id);
2187 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2188}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002189
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002190testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2191 /* MS <-> SGSN: Attach
2192 * MS -> SGSN: Detach Req (Power off)
2193 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2194 */
2195 var BSSGP_ConnHdlr vc_conn;
2196 var integer id := 33;
2197 var charstring imsi := hex2str(f_gen_imsi(id));
2198
2199 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002200 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002201 vc_conn.done;
2202
2203 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002204 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002205}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002206
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002207/* Attempt an attach, but loose the Identification Request (IMEI) */
2208private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2209 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002210 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002211
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002212 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 +02002213
2214 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002215 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002216 /* break */
2217 }
Harald Welte955aa942019-05-03 01:29:29 +02002218 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002219 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002220 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002221 repeat;
2222 }
Harald Welte955aa942019-05-03 01:29:29 +02002223 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002224 /* ignore ID REQ IMEI */
2225 count_req := count_req + 1;
2226 repeat;
2227 }
2228 }
2229 if (count_req != 5) {
2230 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002231 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002232 }
2233 setverdict(pass);
2234}
2235
2236testcase TC_attach_no_imei_response() runs on test_CT {
2237 /* MS -> SGSN: Attach Request IMSI
2238 * MS <- SGSN: Identity Request IMSI (optional)
2239 * MS -> SGSN: Identity Response IMSI (optional)
2240 * MS <- SGSN: Identity Request IMEI
2241 * MS -x SGSN: no response
2242 * MS <- SGSN: re-send: Identity Request IMEI 4x
2243 * MS <- SGSN: Attach Reject
2244 */
2245 var BSSGP_ConnHdlr vc_conn;
2246 f_init();
2247 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002248 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 +02002249 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002250 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002251}
2252
Alexander Couzens53f20562018-06-12 16:24:12 +02002253/* Attempt an attach, but loose the Identification Request (IMSI) */
2254private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2255 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002256 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002257
2258 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2259 g_pars.p_tmsi := 'c0000035'O;
2260
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002261 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 +02002262
2263 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002264 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002265 /* break */
2266 }
Harald Welte955aa942019-05-03 01:29:29 +02002267 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002268 /* ignore ID REQ IMSI */
2269 count_req := count_req + 1;
2270 repeat;
2271 }
Harald Welte955aa942019-05-03 01:29:29 +02002272 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002273 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002274 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002275 repeat;
2276 }
2277 }
2278 if (count_req != 5) {
2279 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002280 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002281 }
2282 setverdict(pass);
2283}
2284
2285testcase TC_attach_no_imsi_response() runs on test_CT {
2286 /* MS -> SGSN: Attach Request TMSI (unknown)
2287 * MS <- SGSN: Identity Request IMEI (optional)
2288 * MS -> SGSN: Identity Response IMEI (optional)
2289 * MS <- SGSN: Identity Request IMSI
2290 * MS -x SGSN: no response
2291 * MS <- SGSN: re-send: Identity Request IMSI 4x
2292 * MS <- SGSN: Attach Reject
2293 */
2294 var BSSGP_ConnHdlr vc_conn;
2295 f_init();
2296 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002297 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 +02002298 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002299 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002300}
2301
Alexander Couzenscf818962018-06-05 18:00:00 +02002302private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2303 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2304}
2305
2306testcase TC_attach_check_subscriber_list() runs on test_CT {
2307 /* MS <-> SGSN: Attach
2308 * VTY -> SGSN: Check if MS is in subscriber cache
2309 */
2310 var BSSGP_ConnHdlr vc_conn;
2311 var integer id := 34;
2312 var charstring imsi := hex2str(f_gen_imsi(id));
2313
2314 f_init();
2315 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002316 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002317 vc_conn.done;
2318
2319 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2320 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002321 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002322}
2323
Alexander Couzensf9858652018-06-07 16:14:53 +02002324private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2325 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002326 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002327
2328 /* unregister the old IMSI */
2329 f_bssgp_client_unregister(g_pars.imsi);
2330 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002331 g_pars.imsi := '001010123456700'H;
Alexander Couzens51114d12018-07-31 18:41:56 +02002332 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
Alexander Couzensf9858652018-06-07 16:14:53 +02002333
2334 /* there is no auth */
2335 g_pars.net.expect_auth := false;
2336
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002337 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002338 f_gmm_auth();
2339 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002340 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002341 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002342 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002343 }
Harald Welte955aa942019-05-03 01:29:29 +02002344 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2345 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002346 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002347 setverdict(pass);
2348 }
2349 }
2350}
Alexander Couzens03d12242018-08-07 16:13:52 +02002351
2352private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2353
2354 f_TC_attach_closed_foreign(id);
2355 f_TC_attach_closed_imsi_added(id);
2356
2357}
2358
2359
Alexander Couzensf9858652018-06-07 16:14:53 +02002360testcase TC_attach_closed_add_vty() runs on test_CT {
2361 /* VTY-> SGSN: policy close
2362 * MS -> SGSN: Attach Request
2363 * MS <- SGSN: Identity Request IMSI
2364 * MS -> SGSN: Identity Response IMSI
2365 * MS <- SGSN: Attach Reject
2366 * VTY-> SGSN: policy imsi-acl add IMSI
2367 * MS -> SGSN: Attach Request
2368 * MS <- SGSN: Identity Request IMSI
2369 * MS -> SGSN: Identity Response IMSI
2370 * MS <- SGSN: Identity Request IMEI
2371 * MS -> SGSN: Identity Response IMEI
2372 * MS <- SGSN: Attach Accept
2373 */
2374 var BSSGP_ConnHdlr vc_conn;
2375 f_init();
2376 f_sleep(1.0);
2377 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2378 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002379 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2380 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002381 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002382 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002383 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002384 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002385}
2386
Alexander Couzens0085bd72018-06-12 19:08:44 +02002387/* Attempt an attach, but never answer a Attach Complete */
2388private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2389 var integer count_req := 0;
2390
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002391 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 +02002392 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002393 /* Expect SGSN to perform LU with HLR */
2394 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002395
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002396 timer T := 10.0;
2397 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002398 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002399 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002400 /* break */
2401 }
Harald Welte955aa942019-05-03 01:29:29 +02002402 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002403 /* ignore */
2404 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002405 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002406 repeat;
2407 }
2408 }
2409 if (count_req != 5) {
2410 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002411 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002412 }
2413 setverdict(pass);
2414}
2415
2416testcase TC_attach_check_complete_resend() runs on test_CT {
2417 /* MS -> SGSN: Attach Request IMSI
2418 * MS <- SGSN: Identity Request *
2419 * MS -> SGSN: Identity Response *
2420 * MS <- SGSN: Attach Complete 5x
2421 */
2422 var BSSGP_ConnHdlr vc_conn;
2423 f_init();
2424 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002425 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 +02002426 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002427 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002428}
2429
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002430friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002431 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002432 var PDU_DTAP_PS_MT mt;
2433 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002434
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002435 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002436 p_tmsi := g_pars.p_tmsi;
2437 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002438 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002439 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 +02002440 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002441 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2442 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2443 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002444 setverdict(pass);
2445 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002446 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2447 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2448 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002449 setverdict(pass);
2450 }
2451
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002452 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002453 setverdict(fail, "Unexpected RAU Reject");
2454 mtc.stop;
2455 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002456 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002457 setverdict(fail, "Unexpected RAU Reject");
2458 mtc.stop;
2459 }
2460
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002461 [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 +02002462 key_sts := ?)) {
2463 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2464 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002465 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002466 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002467 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002468 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2469 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002470 }
2471}
2472
Alexander Couzensbfda9212018-07-31 03:17:33 +02002473private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002474 /* first perform regular attach */
2475 f_TC_attach(id);
2476
2477 /* then send RAU */
2478 f_routing_area_update(g_pars.ra);
2479
2480 /* do another RAU */
2481 f_routing_area_update(g_pars.ra);
2482
2483 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2484}
2485
2486testcase TC_attach_rau_a_a() runs on test_CT {
2487 /* MS <-> SGSN: Successful Attach
2488 * MS -> SGSN: Routing Area Update Request
2489 * MS <- SGSN: Routing Area Update Accept
2490 * MS -> SGSN: Routing Area Update Request
2491 * MS <- SGSN: Routing Area Update Accept
2492 * MS -> SGSN: Detach (PowerOff)
2493 */
2494 var BSSGP_ConnHdlr vc_conn;
2495 f_init();
2496 f_sleep(1.0);
2497 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2498 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002499 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002500}
2501
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002502private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002503 f_TC_attach(id);
2504
2505 log("attach complete sending rau");
2506 f_routing_area_update(g_pars.ra, 0);
2507
2508 log("rau complete unregistering");
2509 f_bssgp_client_unregister(g_pars.imsi);
2510 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
2511
2512 log("sending second RAU via different RA");
2513 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2514
2515 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2516}
2517
2518testcase TC_attach_rau_a_b() runs on test_CT {
2519 /* MS <-> SGSN: Successful Attach
2520 * MS -> SGSN: Routing Area _a_ Update Request
2521 * MS <- SGSN: Routing Area _a_ Update Accept
2522 * MS -> SGSN: Routing Area _b_ Update Request
2523 * MS <- SGSN: Routing Area _b_ Update Accept
2524 * MS -> SGSN: Detach (PowerOff)
2525 */
2526 var BSSGP_ConnHdlr vc_conn;
2527 f_init();
2528 f_sleep(1.0);
2529 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2530 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002531 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002532}
2533
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002534private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2535 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002536 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002537 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002538 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002539
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002540 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002541
2542 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002543 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002544 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2545 mtc.stop;
2546 }
Harald Welte955aa942019-05-03 01:29:29 +02002547 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002548 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002549 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002550 repeat;
2551 }
Harald Welte955aa942019-05-03 01:29:29 +02002552 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002553 /* send out a second GMM_Attach Request.
2554 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2555 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002556 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002557 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002558 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002559 }
2560 }
2561 f_sleep(1.0);
2562
2563 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2564 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002565 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002566 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002567 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002568 repeat;
2569 }
Harald Welte955aa942019-05-03 01:29:29 +02002570 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002571 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2572 mtc.stop;
2573 }
Harald Welte955aa942019-05-03 01:29:29 +02002574 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002575 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2576 mtc.stop;
2577 }
Harald Welte955aa942019-05-03 01:29:29 +02002578 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2579 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002580 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002581 setverdict(pass);
2582 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2583 }
2584 }
2585}
2586
2587testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2588 /* Testing if the SGSN ignore Attach Request with the exact same content */
2589 /* MS -> SGSN: Attach Request IMSI
2590 * MS <- SGSN: Identity Request IMSI (optional)
2591 * MS -> SGSN: Identity Response IMSI (optional)
2592 * MS <- SGSN: Identity Request IMEI
2593 * MS -> SGSN: Attach Request (2nd)
2594 * MS <- SGSN: Identity Response IMEI
2595 * MS <- SGSN: Attach Accept
2596 * MS -> SGSN: Attach Complete
2597 */
2598 var BSSGP_ConnHdlr vc_conn;
2599 f_init();
2600 f_sleep(1.0);
2601 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2602 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2603 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002604 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002605}
2606
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002607private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002608 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2609
2610 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2611
2612 /* send Attach Request */
2613 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2614 * 3G auth vectors */
2615 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2616 /* The thing is, if the solSACapability is 'omit', then the
2617 * revisionLevelIndicatior is at the wrong place! */
2618 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002619 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002620
2621 /* do the auth */
2622 var PDU_L3_MS_SGSN l3_mo;
2623 var PDU_L3_SGSN_MS l3_mt;
2624 var default di := activate(as_mm_identity());
2625
2626 var GSUP_IE auth_tuple;
2627 var template AuthenticationParameterAUTNTLV autn;
2628
2629 g_pars.vec := f_gen_auth_vec_3g();
2630 autn := {
2631 elementIdentifier := '28'O,
2632 lengthIndicator := lengthof(g_pars.vec.autn),
2633 autnValue := g_pars.vec.autn
2634 };
2635 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2636 g_pars.vec.sres,
2637 g_pars.vec.kc,
2638 g_pars.vec.ik,
2639 g_pars.vec.ck,
2640 g_pars.vec.autn,
2641 g_pars.vec.res));
2642 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2643 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2644 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2645
2646 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2647 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002648 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002649
2650 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002651 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002652
2653 /* wait for the GSUP resync request */
2654 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2655 g_pars.imsi,
2656 g_pars.vec.auts,
2657 g_pars.vec.rand));
2658
2659 /* generate new key material */
2660 g_pars.vec := f_gen_auth_vec_3g();
2661 autn := {
2662 elementIdentifier := '28'O,
2663 lengthIndicator := lengthof(g_pars.vec.autn),
2664 autnValue := g_pars.vec.autn
2665 };
2666
2667 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2668 g_pars.vec.sres,
2669 g_pars.vec.kc,
2670 g_pars.vec.ik,
2671 g_pars.vec.ck,
2672 g_pars.vec.autn,
2673 g_pars.vec.res));
2674 /* send new key material */
2675 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2676
2677 /* wait for the new Auth Request */
2678 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2679 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002680 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002681 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2682 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2683 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2684 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2685 valueField := substr(g_pars.vec.res, 0, 4)
2686 };
2687 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2688 elementIdentifier := '21'O,
2689 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2690 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2691 };
2692 l3_mo := valueof(auth_ciph_resp);
2693 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2694 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2695 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2696 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2697 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002698 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002699 deactivate(di);
2700
2701 /* Expect SGSN to perform LU with HLR */
2702 f_gmm_gsup_lu_isd();
2703
Harald Welte955aa942019-05-03 01:29:29 +02002704 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2705 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002706 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002707 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002708 setverdict(pass);
2709}
2710
2711testcase TC_attach_usim_resync() runs on test_CT {
2712 /* MS -> SGSN: Attach Request
2713 * MS <- SGSN: Identity Request IMSI
2714 * MS -> SGSN: Identity Response IMSI
2715 * MS <- SGSN: Identity Request IMEI
2716 * MS -> SGSN: Identity Response IMEI
2717 * HLR<- SGSN: SAI Request
2718 * HLR-> SGSN: SAI Response
2719 * MS <- SGSN: Auth Request
2720 * MS -> SGSN: Auth Failure (with AUTS)
2721 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2722 * HLR-> SGSN: SAI Response (new key material)
2723 * MS <- SGSN: Auth Request (new key material)
2724 * MS -> SGSN: Auth Response
2725 * MS <- SGSN: Attach Accept
2726 * MS -> SGSN: Attach Complete
2727 */
2728 var BSSGP_ConnHdlr vc_conn;
2729 f_init();
2730 f_sleep(1.0);
2731 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2732 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002733 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002734}
2735
Harald Weltea05b8072019-04-23 22:35:05 +02002736
2737/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2738private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2739 f_gmm_attach(false, false);
2740 f_sleep(1.0);
2741 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2742 /* try to detach to check if SGSN is still alive */
2743 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2744}
2745testcase TC_llc_null() runs on test_CT {
2746 var BSSGP_ConnHdlr vc_conn;
2747 f_init();
2748 f_sleep(1.0);
2749 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2750 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002751 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002752}
2753
Harald Welte645a1512019-04-23 23:18:23 +02002754/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2755private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2756 f_gmm_attach(false, false);
2757 f_sleep(1.0);
2758 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002759 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002760 setverdict(pass);
2761}
2762testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2763 var BSSGP_ConnHdlr vc_conn;
2764 f_init();
2765 f_sleep(1.0);
2766 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2767 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002768 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002769}
2770
2771/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2772private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2773 f_gmm_attach(false, false);
2774 f_sleep(1.0);
2775 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002776 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002777 setverdict(pass);
2778}
2779testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2780 var BSSGP_ConnHdlr vc_conn;
2781 f_init();
2782 f_sleep(1.0);
2783 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2784 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002785 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002786}
2787
Harald Welte2aaac1b2019-05-02 10:02:53 +02002788/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2789private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2790 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2791 var template (value) XID_Information xid;
2792 var template XID_Information xid_rx;
2793
2794 /* first perform regular attach */
2795 f_TC_attach(id);
2796 /* then activate PDP context */
2797 f_pdp_ctx_act(apars);
2798
2799 /* start MO XID */
2800 xid := { ts_XID_L3(''O) };
2801 xid_rx := { tr_XID_L3(''O) };
2802 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2803 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002804 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002805 [] as_xid(apars);
2806 }
2807 setverdict(pass);
2808}
2809testcase TC_xid_empty_l3() runs on test_CT {
2810 var BSSGP_ConnHdlr vc_conn;
2811 f_init();
2812 f_sleep(1.0);
2813 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2814 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002815 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002816}
2817
2818private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2819 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2820 var template (value) XID_Information xid;
2821 var template XID_Information xid_rx;
2822
2823 /* first perform regular attach */
2824 f_TC_attach(id);
2825 /* then activate PDP context */
2826 f_pdp_ctx_act(apars);
2827
2828 /* start MO XID */
2829 xid := { ts_XID_N201U(1234) };
2830 xid_rx := { tr_XID_N201U(1234) };
2831 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2832 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002833 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002834 [] as_xid(apars);
2835 }
2836 setverdict(pass);
2837}
2838testcase TC_xid_n201u() runs on test_CT {
2839 var BSSGP_ConnHdlr vc_conn;
2840 f_init();
2841 f_sleep(1.0);
2842 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2843 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002844 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002845}
2846
Alexander Couzens6bee0872019-05-11 01:48:50 +02002847private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2848 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2849
2850 /* first perform regular attach */
2851 f_TC_attach(id);
2852 /* then activate PDP context */
2853 f_pdp_ctx_act(apars);
2854 /* do a normal detach */
2855 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2856}
2857
2858testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2859 /* MS -> SGSN: Attach Request
2860 * MS <-> SGSN: [..]
2861 * MS -> SGSN: Attach Complete
2862 * MS -> SGSN: PDP Activate Request
2863 * MS <- SGSN: PDP Activate Accept
2864 * MS -> SGSN: GMM Detach Request
2865 * MS <- SGSN: GMM Detach Accept
2866 */
2867 var BSSGP_ConnHdlr vc_conn;
2868 f_init();
2869 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2870 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002871 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002872}
Harald Welte645a1512019-04-23 23:18:23 +02002873
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002874private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2875 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2876 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2877 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2878 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2879 var PDU_L3_SGSN_MS l3_mt;
2880
2881 f_send_l3(attach_req, 0);
2882
2883 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2884
2885 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2886 alt {
2887 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2888 setverdict(pass);
2889 }
2890 [] BSSGP[0].receive { repeat; }
2891 }
2892}
2893
2894/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2895 * See OS#3957 and OS#4245 for more information.
2896 */
2897testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2898 /*
2899 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2900 * MS <-- SGSN: Identity Request (IMEI)
2901 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2902 */
2903 var BSSGP_ConnHdlr vc_conn;
2904 f_init();
2905 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2906 vc_conn.done;
2907 f_cleanup();
2908}
2909
Harald Welte5ac31492018-02-15 20:39:13 +01002910control {
Harald Welte5b7c8122018-02-16 21:48:17 +01002911 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01002912 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02002913 execute( TC_attach_umts_aka_umts_res() );
2914 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002915 execute( TC_attach_auth_id_timeout() );
2916 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01002917 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01002918 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01002919 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01002920 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01002921 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01002922 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002923 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02002924 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002925 execute( TC_attach_closed_add_vty(), 20.0 );
2926 execute( TC_attach_check_subscriber_list(), 20.0 );
2927 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02002928 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02002929 execute( TC_hlr_location_cancel_request_update(), 20.0 );
2930 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
2931 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
2932 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01002933 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01002934 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02002935 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002936 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002937 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01002938 execute( TC_detach_unknown_nopoweroff() );
2939 execute( TC_detach_unknown_poweroff() );
2940 execute( TC_detach_nopoweroff() );
2941 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01002942 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01002943 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01002944 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01002945 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01002946 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01002947 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02002948 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02002949 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02002950 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02002951 execute( TC_attach_restart_ctr_echo() );
2952 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02002953 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002954 execute( TC_attach_pdp_act_deact_gtp_retrans() );
2955 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002956 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02002957 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002958 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02002959
Harald Welte2aaac1b2019-05-02 10:02:53 +02002960 execute( TC_xid_empty_l3() );
2961 execute( TC_xid_n201u() );
2962
Harald Weltea05b8072019-04-23 22:35:05 +02002963 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02002964 execute( TC_llc_sabm_dm_llgmm() );
2965 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002966
2967 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
2968 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01002969}
Harald Welte96a33b02018-02-04 10:36:22 +01002970
2971
2972
2973}