blob: a602b21506a0935ccd96244dd2aec795d5aeccd0 [file] [log] [blame]
Harald Welte96a33b02018-02-04 10:36:22 +01001module SGSN_Tests {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* Osmocom SGSN test suite in TTCN-3
4 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
5 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
Harald Welte900d01a2019-08-13 13:27:51 +020014friend module SGSN_Tests_Iu;
Alexander Couzens8e1dfd02020-09-07 04:26:20 +020015friend module SGSN_Tests_NS;
Harald Welte900d01a2019-08-13 13:27:51 +020016
Harald Welte96a33b02018-02-04 10:36:22 +010017import from General_Types all;
18import from Osmocom_Types all;
Harald Welte557c9f82020-09-12 21:30:17 +020019import from GSM_Types all;
Harald Welte37692d82018-02-18 15:21:34 +010020import from Native_Functions all;
Harald Welte96a33b02018-02-04 10:36:22 +010021import from NS_Types all;
22import from NS_Emulation all;
23import from BSSGP_Types all;
24import from BSSGP_Emulation all;
Harald Welte5ac31492018-02-15 20:39:13 +010025import from Osmocom_Gb_Types all;
Harald Welte26fbb6e2019-04-14 17:32:46 +020026import from SCCPasp_Types all;
Harald Welte5ac31492018-02-15 20:39:13 +010027
28import from MobileL3_CommonIE_Types all;
29import from MobileL3_GMM_SM_Types all;
30import from MobileL3_Types all;
31import from L3_Templates all;
32import from L3_Common all;
33
34import from GSUP_Emulation all;
35import from GSUP_Types all;
36import from IPA_Emulation all;
37
Harald Welte26fbb6e2019-04-14 17:32:46 +020038import from RAN_Adapter all;
39import from RAN_Emulation all;
40import from RANAP_Templates all;
41import from RANAP_PDU_Descriptions all;
42import from RANAP_IEs all;
43
Harald Welteeded9ad2018-02-17 20:57:34 +010044import from GTP_Emulation all;
45import from GTP_Templates all;
46import from GTP_CodecPort all;
47import from GTPC_Types all;
48import from GTPU_Types all;
49
Harald Weltea2526a82018-02-18 19:03:36 +010050import from LLC_Types all;
51import from LLC_Templates all;
52
53import from SNDCP_Types all;
54
Harald Weltebd194722018-02-16 22:11:08 +010055import from TELNETasp_PortType all;
56import from Osmocom_VTY_Functions all;
57
Neels Hofmeyr8df7d152018-03-14 19:03:28 +010058import from GSM_RR_Types all;
59
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +020060import from MobileL3_MM_Types all;
61
Harald Welteeded9ad2018-02-17 20:57:34 +010062
Harald Welte5ac31492018-02-15 20:39:13 +010063modulepar {
64 /* IP/port on which we run our internal GSUP/HLR emulation */
65 charstring mp_hlr_ip := "127.0.0.1";
66 integer mp_hlr_port := 4222;
Harald Welteeded9ad2018-02-17 20:57:34 +010067 charstring mp_ggsn_ip := "127.0.0.2";
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +020068 integer mp_echo_interval := 5; /* in seconds. Only used in test enabling g_use_echo */
Alexander Couzens2c12b242018-07-31 00:30:11 +020069
Alexander Couzensf3c1b412018-08-24 00:42:51 +020070 NSConfigurations mp_nsconfig := {
71 {
Harald Welte5e514fa2018-07-05 00:01:45 +020072 nsei := 96,
73 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010074 handle_sns := false,
75 nsvc := {
76 {
77 provider := {
78 ip := {
79 address_family := AF_INET,
80 local_udp_port := 21010,
81 local_ip := "127.0.0.1",
82 remote_udp_port := 23000,
83 remote_ip := "127.0.0.1"
84 }
85 },
86 nsvci := 97
87 }
88 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +020089 },
90 {
Harald Welte5e514fa2018-07-05 00:01:45 +020091 nsei := 97,
92 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +010093 handle_sns := false,
94 nsvc := {
95 {
96 provider := {
97 ip := {
98 address_family := AF_INET,
99 local_udp_port := 21011,
100 local_ip := "127.0.0.1",
101 remote_udp_port := 23000,
102 remote_ip := "127.0.0.1"
103 }
104 },
105 nsvci := 98
106 }
107 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200108 },
109 {
Harald Welte5e514fa2018-07-05 00:01:45 +0200110 nsei := 98,
111 role_sgsn := false,
Harald Welte90f19742020-11-06 19:34:40 +0100112 handle_sns := false,
113 nsvc := {
114 {
115 provider := {
116 ip := {
117 address_family := AF_INET,
118 local_udp_port := 21012,
119 local_ip := "127.0.0.1",
120 remote_udp_port := 23000,
121 remote_ip := "127.0.0.1"
122 }
123 },
124 nsvci := 99
125 }
126 }
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200127 }
Alexander Couzens2c12b242018-07-31 00:30:11 +0200128 };
Harald Welte26fbb6e2019-04-14 17:32:46 +0200129
130 RAN_Configurations mp_ranap_cfg := {
131 {
132 transport := RANAP_TRANSPORT_IuCS,
133 sccp_service_type := "mtp3_itu",
134 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
135 own_pc := 195,
136 own_ssn := 142,
137 peer_pc := 188, /* 0.23.4 */
138 peer_ssn := 142,
139 sio := '83'O,
140 rctx := 2
141 }
142 }
Harald Welte5ac31492018-02-15 20:39:13 +0100143};
144
Harald Welte5339b2e2020-10-04 22:52:56 +0200145const integer NUM_BVC_PER_NSE := 1;
Harald Welte5ac31492018-02-15 20:39:13 +0100146type record GbInstance {
147 NS_CT vc_NS,
148 BSSGP_CT vc_BSSGP,
Harald Welte5339b2e2020-10-04 22:52:56 +0200149 BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
Harald Welte5ac31492018-02-15 20:39:13 +0100150 BssgpConfig cfg
151};
Harald Welte96a33b02018-02-04 10:36:22 +0100152
Harald Welte2fa771f2019-05-02 20:13:53 +0200153const integer NUM_GB := 3;
154type record length(NUM_GB) of GbInstance GbInstances;
155type record length(NUM_GB) of NSConfiguration NSConfigurations;
156type record length(NUM_GB) of BssgpCellId BssgpCellIds;
Alexander Couzens51114d12018-07-31 18:41:56 +0200157
Harald Welte26fbb6e2019-04-14 17:32:46 +0200158const integer NUM_RNC := 1;
159type record of RAN_Configuration RAN_Configurations;
160
Harald Welte96a33b02018-02-04 10:36:22 +0100161type component test_CT {
Alexander Couzens51114d12018-07-31 18:41:56 +0200162 var GbInstances g_gb;
Harald Welte26fbb6e2019-04-14 17:32:46 +0200163 var RAN_Adapter g_ranap[NUM_RNC];
Alexander Couzens1552e792019-07-23 20:38:39 +0200164 var boolean g_ranap_enable := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100165
Harald Welte5ac31492018-02-15 20:39:13 +0100166 var GSUP_Emulation_CT vc_GSUP;
167 var IPA_Emulation_CT vc_GSUP_IPA;
168 /* only to get events from IPA underneath GSUP */
169 port IPA_CTRL_PT GSUP_IPA_EVENT;
Harald Welte96a33b02018-02-04 10:36:22 +0100170
Harald Welte5339b2e2020-10-04 22:52:56 +0200171 /* only needed at start to get the per-BVC references */
172 port BSSGP_CT_PROC_PT PROC;
173
Harald Welteeded9ad2018-02-17 20:57:34 +0100174 var GTP_Emulation_CT vc_GTP;
175
Harald Weltebd194722018-02-16 22:11:08 +0100176 port TELNETasp_PT SGSNVTY;
177
Harald Welte96a33b02018-02-04 10:36:22 +0100178 var boolean g_initialized := false;
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200179 var boolean g_use_echo := false;
Harald Welte96a33b02018-02-04 10:36:22 +0100180};
181
Harald Welte26fbb6e2019-04-14 17:32:46 +0200182type component BSSGP_ConnHdlr extends BSSGP_Client_CT, GSUP_ConnHdlr, GTP_ConnHdlr, RAN_ConnHdlr {
Harald Welte5ac31492018-02-15 20:39:13 +0100183 var BSSGP_ConnHdlrPars g_pars;
Harald Welte62e29582018-02-16 21:17:11 +0100184 timer g_Tguard;
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200185 var LLC_Entities llc;
Harald Welte5ac31492018-02-15 20:39:13 +0100186}
187
188type record SGSN_ConnHdlrNetworkPars {
189 boolean expect_ptmsi,
190 boolean expect_auth,
191 boolean expect_ciph
192};
193
194type record BSSGP_ConnHdlrPars {
195 /* IMEI of the simulated ME */
196 hexstring imei,
Alexander Couzens8f0fb002018-05-02 19:30:55 +0200197 /* IMSI of the simulated MS */
Harald Welte5ac31492018-02-15 20:39:13 +0100198 hexstring imsi,
199 /* MSISDN of the simulated MS (probably unused) */
200 hexstring msisdn,
201 /* P-TMSI allocated to the simulated MS */
202 OCT4 p_tmsi optional,
Harald Welte04683d02018-02-16 22:43:45 +0100203 OCT3 p_tmsi_sig optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100204 /* TLLI of the simulated MS */
205 OCT4 tlli,
Harald Weltef70997d2018-02-17 10:11:19 +0100206 OCT4 tlli_old optional,
Harald Welte5ac31492018-02-15 20:39:13 +0100207 RoutingAreaIdentificationV ra optional,
Alexander Couzens51114d12018-07-31 18:41:56 +0200208 BssgpCellIds bssgp_cell_id,
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200209 /* Tracks the RNC state. If true next L3 message will be sent with InitiualUe */
210 boolean rnc_send_initial_ue,
Harald Welte5ac31492018-02-15 20:39:13 +0100211 AuthVector vec optional,
Harald Welte62e29582018-02-16 21:17:11 +0100212 SGSN_ConnHdlrNetworkPars net,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200213 float t_guard,
214 /* only in IuPS / RANAP case */
Alexander Couzens1552e792019-07-23 20:38:39 +0200215 SCCP_PAR_Address sccp_addr_local optional,
216 SCCP_PAR_Address sccp_addr_peer optional
Harald Welte5ac31492018-02-15 20:39:13 +0100217};
218
Alexander Couzens89508702018-07-31 04:16:10 +0200219private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200220 /* mcc_mnc is encoded as of 24.008 10.5.5.15 */
Alexander Couzens89508702018-07-31 04:16:10 +0200221 var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;
222
223 var RoutingAreaIdentificationV ret := {
224 mccDigit1 := mcc_mnc[0],
225 mccDigit2 := mcc_mnc[1],
226 mccDigit3 := mcc_mnc[2],
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200227 mncDigit3 := mcc_mnc[3],
228 mncDigit1 := mcc_mnc[4],
229 mncDigit2 := mcc_mnc[5],
Alexander Couzens89508702018-07-31 04:16:10 +0200230 lac := int2oct(cell_id.ra_id.lai.lac, 16),
231 rac := int2oct(cell_id.ra_id.rac, 8)
232 }
233 return ret;
234};
235
Alexander Couzens51114d12018-07-31 18:41:56 +0200236private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
237 gb.vc_NS := NS_CT.create(id & "-NS" & int2str(offset));
238 gb.vc_BSSGP := BSSGP_CT.create(id & "-BSSGP" & int2str(offset));
Harald Welte5ac31492018-02-15 20:39:13 +0100239 /* connect lower end of BSSGP emulation with NS upper port */
240 connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
Harald Welte5ac31492018-02-15 20:39:13 +0100241
Alexander Couzensf3c1b412018-08-24 00:42:51 +0200242 gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
Harald Welte5339b2e2020-10-04 22:52:56 +0200243 gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
244 /* resolve the per-BVC component references */
245 for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
246 connect(self:PROC, gb.vc_BSSGP:PROC);
247 gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
248 disconnect(self:PROC, gb.vc_BSSGP:PROC);
249 }
Harald Welte5ac31492018-02-15 20:39:13 +0100250}
251
252private function f_init_gsup(charstring id) runs on test_CT {
253 id := id & "-GSUP";
254 var GsupOps ops := {
255 create_cb := refers(GSUP_Emulation.ExpectedCreateCallback)
256 };
257
258 vc_GSUP_IPA := IPA_Emulation_CT.create(id & "-IPA");
259 vc_GSUP := GSUP_Emulation_CT.create(id);
260
261 map(vc_GSUP_IPA:IPA_PORT, system:IPA_CODEC_PT);
262 connect(vc_GSUP:GSUP, vc_GSUP_IPA:IPA_GSUP_PORT);
263 /* we use this hack to get events like ASP_IPA_EVENT_UP */
264 connect(vc_GSUP_IPA:IPA_CTRL_PORT, self:GSUP_IPA_EVENT);
265
266 vc_GSUP.start(GSUP_Emulation.main(ops, id));
267 vc_GSUP_IPA.start(IPA_Emulation.main_server(mp_hlr_ip, mp_hlr_port));
268
269 /* wait for incoming connection to GSUP port before proceeding */
270 timer T := 10.0;
271 T.start;
272 alt {
Vadim Yanitskiy61564be2020-05-18 20:44:14 +0700273 [] GSUP_IPA_EVENT.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { }
Harald Welte5ac31492018-02-15 20:39:13 +0100274 [] T.timeout {
275 setverdict(fail, "No connection to GSUP Port");
Daniel Willmannafce8662018-07-06 23:11:32 +0200276 mtc.stop;
Harald Welte5ac31492018-02-15 20:39:13 +0100277 }
278 }
279}
280
Harald Welteeded9ad2018-02-17 20:57:34 +0100281private function f_init_gtp(charstring id) runs on test_CT {
282 id := id & "-GTP";
283
284 var GtpEmulationCfg gtp_cfg := {
285 gtpc_bind_ip := mp_ggsn_ip,
286 gtpc_bind_port := GTP1C_PORT,
287 gtpu_bind_ip := mp_ggsn_ip,
288 gtpu_bind_port := GTP1U_PORT,
289 sgsn_role := false
290 };
291
292 vc_GTP := GTP_Emulation_CT.create(id);
293 vc_GTP.start(GTP_Emulation.main(gtp_cfg));
294}
295
Alexander Couzens8e1dfd02020-09-07 04:26:20 +0200296friend function f_init_vty() runs on test_CT {
Harald Weltebd194722018-02-16 22:11:08 +0100297 map(self:SGSNVTY, system:SGSNVTY);
298 f_vty_set_prompts(SGSNVTY);
299 f_vty_transceive(SGSNVTY, "enable");
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200300 f_vty_transceive(SGSNVTY, "reset sgsn state");
Harald Weltebd194722018-02-16 22:11:08 +0100301 f_vty_config(SGSNVTY, "sgsn", "auth-policy remote");
302}
303
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200304private function f_vty_enable_echo_interval(boolean enable) runs on test_CT {
305 if (enable) {
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +0200306 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 echo-interval " & int2str(mp_echo_interval));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200307 } else {
308 f_vty_config(SGSNVTY, "sgsn", "ggsn 0 no echo-interval");
309 }
310}
311
Harald Weltebd194722018-02-16 22:11:08 +0100312
Alexander Couzensc7dddbd2019-04-11 19:18:35 +0200313/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
314function f_init(BcdMccMnc mcc_mnc := '262F42'H) runs on test_CT {
Harald Welte26fbb6e2019-04-14 17:32:46 +0200315 var integer i;
316
Harald Welte96a33b02018-02-04 10:36:22 +0100317 if (g_initialized == true) {
318 return;
319 }
320 g_initialized := true;
Harald Welte5ac31492018-02-15 20:39:13 +0100321 g_gb[0].cfg := {
322 nsei := 96,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200323 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200324 bvc := {
325 {
326 bvci := 196,
327 cell_id := {
328 ra_id := {
329 lai := {
330 mcc_mnc := mcc_mnc,
331 lac := 13135
332 },
333 rac := 0
334 },
335 cell_id := 20960
336 },
337 depth := BSSGP_DECODE_DEPTH_L3
338 }
339 }
Harald Welte5ac31492018-02-15 20:39:13 +0100340 };
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200341 g_gb[1].cfg := {
342 nsei := 97,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200343 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200344 bvc := {
345 {
346 bvci := 210,
347 cell_id := {
348 ra_id := {
349 lai := {
350 mcc_mnc := mcc_mnc,
351 lac := 13200
352 },
353 rac := 0
354 },
355 cell_id := 20961
356 },
357 depth := BSSGP_DECODE_DEPTH_L3
358 }
359 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200360 };
361 g_gb[2].cfg := {
362 nsei := 98,
Oliver Smithaac9b9c2019-09-02 08:36:36 +0200363 sgsn_role := false,
Harald Welte5339b2e2020-10-04 22:52:56 +0200364 bvc := {
365 {
366 bvci := 220,
367 cell_id := {
368 ra_id := {
369 lai := {
370 mcc_mnc := mcc_mnc,
371 lac := 13300
372 },
373 rac := 0
374 },
375 cell_id := 20962
376 },
377 depth := BSSGP_DECODE_DEPTH_L3
378 }
379 }
Alexander Couzens5e2ba752018-07-03 15:13:07 +0200380 };
Harald Welte96a33b02018-02-04 10:36:22 +0100381
Alexander Couzens1d1744f2018-08-07 11:56:14 +0200382 f_init_vty();
Alexander Couzens51114d12018-07-31 18:41:56 +0200383 f_init_gb(g_gb[0], "SGSN_Test-Gb0", 0);
384 f_init_gb(g_gb[1], "SGSN_Test-Gb1", 1);
385 f_init_gb(g_gb[2], "SGSN_Test-Gb2", 2);
Harald Welte26fbb6e2019-04-14 17:32:46 +0200386
Alexander Couzens1552e792019-07-23 20:38:39 +0200387 if (g_ranap_enable) {
388 for (i := 0; i < NUM_RNC; i := i+1) {
389 f_ran_adapter_init(g_ranap[i], mp_ranap_cfg[i], "SGSN_Test_" & int2str(i), RNC_RanOps);
390 f_ran_adapter_start(g_ranap[i]);
391 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200392 }
Harald Welte5ac31492018-02-15 20:39:13 +0100393 f_init_gsup("SGSN_Test");
Harald Welteeded9ad2018-02-17 20:57:34 +0100394 f_init_gtp("SGSN_Test");
Pau Espin Pedroldc27e482018-07-10 14:02:49 +0200395 f_vty_enable_echo_interval(g_use_echo);
Harald Welte5ac31492018-02-15 20:39:13 +0100396}
Harald Welte96a33b02018-02-04 10:36:22 +0100397
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200398function f_cleanup() runs on test_CT {
399 var integer i;
Alexander Couzens1552e792019-07-23 20:38:39 +0200400 if (g_ranap_enable) {
401 for (i := 0; i < NUM_RNC; i := i+1) {
402 f_ran_adapter_cleanup(g_ranap[i]);
403 }
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200404 }
405 self.stop;
406}
407
Harald Welte26fbb6e2019-04-14 17:32:46 +0200408private function RncUnitdataCallback(RANAP_PDU ranap)
409runs on RAN_Emulation_CT return template RANAP_PDU {
410 var template RANAP_PDU resp := omit;
411
412 log ("RANAP_RncUnitDataCallback");
413 /* answer all RESET with RESET ACK */
414 if (match(ranap, tr_RANAP_Reset)) {
415 log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
416 var CN_DomainIndicator dom;
417 dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
418 resp := ts_RANAP_ResetAck(dom);
419 }
420 return resp;
421}
422
423const RanOps RNC_RanOps := {
424 ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
425 ranap_unitdata_cb := refers(RncUnitdataCallback),
426 ps_domain := true,
427 decode_dtap := true,
428 role_ms := true,
429 protocol := RAN_PROTOCOL_RANAP,
430 transport := RANAP_TRANSPORT_IuCS,
431 use_osmux := false,
432 sccp_addr_local := omit,
433 sccp_addr_peer := omit
434};
435
Harald Welte5ac31492018-02-15 20:39:13 +0100436type function void_fn(charstring id) runs on BSSGP_ConnHdlr;
437
438/* helper function to create, connect and start a BSSGP_ConnHdlr component */
Alexander Couzens51114d12018-07-31 18:41:56 +0200439function f_start_handler(void_fn fn, charstring id, GbInstances gb, integer imsi_suffix,
Harald Welte62e29582018-02-16 21:17:11 +0100440 float t_guard := 30.0)
Harald Welte5ac31492018-02-15 20:39:13 +0100441runs on test_CT return BSSGP_ConnHdlr {
442 var BSSGP_ConnHdlr vc_conn;
443 var SGSN_ConnHdlrNetworkPars net_pars := {
444 expect_ptmsi := true,
445 expect_auth := true,
446 expect_ciph := false
447 };
448 var BSSGP_ConnHdlrPars pars := {
449 imei := f_gen_imei(imsi_suffix),
450 imsi := f_gen_imsi(imsi_suffix),
451 msisdn := f_gen_msisdn(imsi_suffix),
452 p_tmsi := omit,
Harald Welte04683d02018-02-16 22:43:45 +0100453 p_tmsi_sig := omit,
Harald Welte14a0f942018-02-16 20:42:23 +0100454 tlli := f_gprs_tlli_random(),
Harald Weltef70997d2018-02-17 10:11:19 +0100455 tlli_old := omit,
Harald Welte5ac31492018-02-15 20:39:13 +0100456 ra := omit,
Harald Welte5339b2e2020-10-04 22:52:56 +0200457 bssgp_cell_id := {
458 gb[0].cfg.bvc[0].cell_id,
459 gb[1].cfg.bvc[0].cell_id,
460 gb[2].cfg.bvc[0].cell_id
461 },
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200462 rnc_send_initial_ue := true,
Harald Welte5ac31492018-02-15 20:39:13 +0100463 vec := omit,
Harald Welte62e29582018-02-16 21:17:11 +0100464 net := net_pars,
Harald Welte26fbb6e2019-04-14 17:32:46 +0200465 t_guard := t_guard,
Alexander Couzens1552e792019-07-23 20:38:39 +0200466 sccp_addr_local := omit,
467 sccp_addr_peer := omit
Harald Welte5ac31492018-02-15 20:39:13 +0100468 };
469
Alexander Couzens1552e792019-07-23 20:38:39 +0200470 if (g_ranap_enable) {
471 pars.sccp_addr_local := g_ranap[0].sccp_addr_own;
472 pars.sccp_addr_peer := g_ranap[0].sccp_addr_peer;
473 }
474
Harald Welte5ac31492018-02-15 20:39:13 +0100475 vc_conn := BSSGP_ConnHdlr.create(id);
Harald Welte5339b2e2020-10-04 22:52:56 +0200476
477 connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
478 connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
479 connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
480
481 connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
482 connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
483 connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
484
485 connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
486 connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
487 connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
Harald Welte5ac31492018-02-15 20:39:13 +0100488
Harald Welte26fbb6e2019-04-14 17:32:46 +0200489 /* FIXME: support multiple RNCs */
Alexander Couzens1552e792019-07-23 20:38:39 +0200490 if (g_ranap_enable) {
491 connect(vc_conn:BSSAP, g_ranap[0].vc_RAN:CLIENT);
492 connect(vc_conn:BSSAP_PROC, g_ranap[0].vc_RAN:PROC);
493 }
Harald Welte26fbb6e2019-04-14 17:32:46 +0200494
Harald Welte5ac31492018-02-15 20:39:13 +0100495 connect(vc_conn:GSUP, vc_GSUP:GSUP_CLIENT);
496 connect(vc_conn:GSUP_PROC, vc_GSUP:GSUP_PROC);
497
Harald Welteeded9ad2018-02-17 20:57:34 +0100498 connect(vc_conn:GTP, vc_GTP:CLIENT);
499 connect(vc_conn:GTP_PROC, vc_GTP:CLIENT_PROC);
500
Harald Welte5ac31492018-02-15 20:39:13 +0100501 vc_conn.start(f_handler_init(fn, id, pars));
502 return vc_conn;
503}
504
Harald Welte62e29582018-02-16 21:17:11 +0100505private altstep as_Tguard() runs on BSSGP_ConnHdlr {
506 [] g_Tguard.timeout {
507 setverdict(fail, "Tguard timeout");
Daniel Willmannafce8662018-07-06 23:11:32 +0200508 mtc.stop;
Harald Welte62e29582018-02-16 21:17:11 +0100509 }
510}
511
Harald Welte5ac31492018-02-15 20:39:13 +0100512/* first function called in every ConnHdlr */
513private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
514runs on BSSGP_ConnHdlr {
515 /* do some common stuff like setting up g_pars */
516 g_pars := pars;
517
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200518 llc := f_llc_create(false);
519
Harald Welte5ac31492018-02-15 20:39:13 +0100520 /* register with BSSGP core */
Harald Welte5339b2e2020-10-04 22:52:56 +0200521 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welte5ac31492018-02-15 20:39:13 +0100522 /* tell GSUP dispatcher to send this IMSI to us */
523 f_create_gsup_expect(hex2str(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100524 /* tell GTP dispatcher to send this IMSI to us */
525 f_gtp_register_imsi(g_pars.imsi);
Harald Welte5ac31492018-02-15 20:39:13 +0100526
Harald Welte62e29582018-02-16 21:17:11 +0100527 g_Tguard.start(pars.t_guard);
528 activate(as_Tguard());
529
Harald Welte5ac31492018-02-15 20:39:13 +0100530 /* call the user-supplied test case function */
531 fn.apply(id);
532 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte96a33b02018-02-04 10:36:22 +0100533}
534
535/* TODO:
Harald Welte96a33b02018-02-04 10:36:22 +0100536 * Detach without Attach
537 * SM procedures without attach / RAU
538 * ATTACH / RAU
539 ** with / without authentication
540 ** with / without P-TMSI allocation
Harald Welte96a33b02018-02-04 10:36:22 +0100541 * re-transmissions of LLC frames
542 * PDP Context activation
543 ** with different GGSN config in SGSN VTY
544 ** with different PDP context type (v4/v6/v46)
545 ** timeout from GGSN
Harald Welte6f203162018-02-18 22:04:55 +0100546 ** multiple / secondary PDP context
Harald Welte96a33b02018-02-04 10:36:22 +0100547 */
548
549testcase TC_wait_ns_up() runs on test_CT {
550 f_init();
551 f_sleep(20.0);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200552 f_cleanup();
Harald Welte96a33b02018-02-04 10:36:22 +0100553}
554
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200555friend function is_gb(integer ran_index) return boolean {
556 return ran_index < NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200557}
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200558friend function is_iu(integer ran_index) return boolean {
559 return ran_index >= NUM_GB;
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200560}
561
Alexander Couzens0507ec32019-09-15 22:41:22 +0200562function f_send_llc(template (value) PDU_LLC llc_pdu, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltea05b8072019-04-23 22:35:05 +0200563 var octetstring llc_enc := enc_PDU_LLC(valueof(llc_pdu));
Alexander Couzens0507ec32019-09-15 22:41:22 +0200564 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 +0200565}
566
Alexander Couzens0507ec32019-09-15 22:41:22 +0200567private 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 +0200568 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
569 var BIT4 sapi := f_llc_sapi_by_l3_mo(valueof(l3_mo));
570 var integer n_u := f_llc_get_n_u_tx(llc[bit2int(sapi)]);
Alexander Couzens0507ec32019-09-15 22:41:22 +0200571 f_send_llc(ts_LLC_UI(l3_enc, sapi, '0'B, n_u), ran_index);
Alexander Couzenscdfb7512018-07-31 15:37:14 +0200572}
573
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200574/* trigger sending of a RANAP InitialUE and wait for SCCP connection confirmation */
575function f_send_l3_initial_ue(template (value) PDU_L3_MS_SGSN l3_mo) runs on BSSGP_ConnHdlr {
576 log("Sending InitialUE: ", l3_mo);
577 var octetstring l3_enc := enc_PDU_L3_MS_SGSN(valueof(l3_mo));
578 var RANAP_PDU ranap;
579 var LAI lai := {
580 pLMNidentity := '62F224'O,
581 lAC := '1234'O,
582 iE_Extensions := omit
583 };
584 var SAI sai := {
585 pLMNidentity := lai.pLMNidentity,
586 lAC := lai.lAC,
587 sAC := '0000'O, /* FIXME */
588 iE_Extensions := omit
589 };
590 var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24); /* FIXME */
591 var GlobalRNC_ID grnc_id := {
592 pLMNidentity := lai.pLMNidentity,
593 rNC_ID := 2342 /* FIXME */
594 };
595
596 ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
597 BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_local, ranap));
598 alt {
599 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
600 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
601 setverdict(fail, "DISC.ind from SCCP");
602 mtc.stop;
603 }
604 }
605}
606
607/* send a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzens0507ec32019-09-15 22:41:22 +0200608function f_send_l3(template (value) PDU_L3_MS_SGSN l3_mo, integer ran_index := 0) runs on BSSGP_ConnHdlr {
609 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200610 if (g_pars.rnc_send_initial_ue) {
611 g_pars.rnc_send_initial_ue := false;
612 f_send_l3_initial_ue(l3_mo);
613 } else {
614 BSSAP.send(ts_PDU_DTAP_PS_MO(l3_mo));
615 }
616 } else {
Alexander Couzens0507ec32019-09-15 22:41:22 +0200617 f_send_l3_gmm_llc(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200618 }
619}
620
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200621altstep as_mm_identity(integer ran_index := 0) runs on BSSGP_ConnHdlr {
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700622 var MobileIdentityLV mi;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200623 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('001'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100624 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200625 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100626 repeat;
627 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200628 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('001'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200629 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200630 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200631 repeat;
632 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200633 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_ID_REQ('010'B)) {
Harald Welte5ac31492018-02-15 20:39:13 +0100634 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200635 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200636 repeat;
637 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200638 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_ID_REQ('010'B))) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200639 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200640 f_send_l3(ts_GMM_ID_RESP(mi), ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100641 repeat;
642 }
643}
Harald Welte96a33b02018-02-04 10:36:22 +0100644
Harald Welteca362462019-05-02 20:11:21 +0200645/* receive a L3 (GMM/SM) message over whatever is the appropriate lower-layer bearer */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200646function f_receive_l3(template PDU_L3_SGSN_MS rx_tpl := ?, integer ran_index := 0)
Harald Welteca362462019-05-02 20:11:21 +0200647runs on BSSGP_ConnHdlr return PDU_L3_SGSN_MS {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200648 var PDU_DTAP_PS_MT mt;
Harald Welteca362462019-05-02 20:11:21 +0200649 var PDU_L3_SGSN_MS l3_mt;
650 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200651 [is_gb(ran_index)] BSSGP[ran_index].receive(rx_tpl) -> value l3_mt { }
652 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(rx_tpl)) -> value mt {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200653 l3_mt := mt.dtap;
654 }
Harald Welteca362462019-05-02 20:11:21 +0200655 }
656 return l3_mt;
657}
658
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200659/* perform GMM authentication (if expected).
660 * Note, for umts_aka_challenge to work, the revisionLevelIndicatior needs to
661 * be 1 to mark R99 capability, in the GMM Attach Request, see f_gmm_attach(). */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200662function 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 +0100663 var PDU_L3_MS_SGSN l3_mo;
664 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200665 var default di := activate(as_mm_identity(ran_index));
Harald Welte5ac31492018-02-15 20:39:13 +0100666 if (g_pars.net.expect_auth) {
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200667 var GSUP_IE auth_tuple;
668 var template AuthenticationParameterAUTNTLV autn;
669
670 if (umts_aka_challenge) {
671 g_pars.vec := f_gen_auth_vec_3g();
672 autn := {
673 elementIdentifier := '28'O,
674 lengthIndicator := lengthof(g_pars.vec.autn),
675 autnValue := g_pars.vec.autn
676 };
677
678 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
679 g_pars.vec.sres,
680 g_pars.vec.kc,
681 g_pars.vec.ik,
682 g_pars.vec.ck,
683 g_pars.vec.autn,
684 g_pars.vec.res));
685 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
686 } else {
687 g_pars.vec := f_gen_auth_vec_2g();
688 autn := omit;
689 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
690 g_pars.vec.sres,
691 g_pars.vec.kc));
692 log("GSUP sends only 2G auth tuple", auth_tuple);
693 }
Harald Welteca362462019-05-02 20:11:21 +0200694
Harald Welte5ac31492018-02-15 20:39:13 +0100695 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
696 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200697
698 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
699 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200700 l3_mt := f_receive_l3(auth_ciph_req, ran_index);
Harald Welte5ac31492018-02-15 20:39:13 +0100701 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200702 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
703
704 if (umts_aka_challenge and not force_gsm_sres) {
705 /* set UMTS response instead */
706 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
707 valueField := substr(g_pars.vec.res, 0, 4)
708 };
709 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
710 elementIdentifier := '21'O,
711 lengthIndicator := lengthof(g_pars.vec.res) - 4,
712 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
713 };
714 }
715
716 l3_mo := valueof(auth_ciph_resp);
Harald Welte5ac31492018-02-15 20:39:13 +0100717 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
718 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
719 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
720 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
721 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200722 f_send_l3(l3_mo, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200723
724 /* Security Mode Command + Complete on Iu case */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200725 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200726 BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?, uia_key := oct2bit(g_pars.vec.ik),
727 key_sts := ?)) {
728 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
729 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +0200730 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200731 }
732 }
Harald Welte76dee092018-02-16 22:12:59 +0100733 } else {
734 /* wait for identity procedure */
735 f_sleep(1.0);
Harald Welte5ac31492018-02-15 20:39:13 +0100736 }
Harald Welte76dee092018-02-16 22:12:59 +0100737
Harald Welte5ac31492018-02-15 20:39:13 +0100738 deactivate(di);
739}
740
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200741function f_upd_ptmsi_and_tlli(OCT4 p_tmsi, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Weltef70997d2018-02-17 10:11:19 +0100742 g_pars.p_tmsi := p_tmsi;
743 /* update TLLI */
744 g_pars.tlli_old := g_pars.tlli;
745 g_pars.tlli := g_pars.p_tmsi or4b 'c0000000'O;
Daniel Willmann1c2ff0f2020-01-28 14:39:25 +0100746 if (is_gb(ran_index)) {
747 f_bssgp_client_llgmm_assign(g_pars.tlli_old, g_pars.tlli, BSSGP_PROC[ran_index]);
748 }
Harald Weltef70997d2018-02-17 10:11:19 +0100749}
750
Harald Welte04683d02018-02-16 22:43:45 +0100751function f_process_attach_accept(PDU_GMM_AttachAccept aa) runs on BSSGP_ConnHdlr {
752 /* mandatory IE */
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100753 var hexstring aa_plmn := f_RAI_to_plmn_hexstr(aa.routingAreaIdentification);
Alexander Couzens51114d12018-07-31 18:41:56 +0200754 if (not (g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc == aa_plmn)) {
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100755 setverdict(fail, "mismatching PLMN in Attach Accept: " & hex2str(aa_plmn)
Alexander Couzens51114d12018-07-31 18:41:56 +0200756 & "; expected " & hex2str(g_pars.bssgp_cell_id[0].ra_id.lai.mcc_mnc));
Daniel Willmannafce8662018-07-06 23:11:32 +0200757 mtc.stop;
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100758 }
Harald Welte04683d02018-02-16 22:43:45 +0100759 g_pars.ra := aa.routingAreaIdentification;
760 if (ispresent(aa.allocatedPTMSI)) {
761 if (not g_pars.net.expect_ptmsi) {
762 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200763 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100764 }
Harald Weltef70997d2018-02-17 10:11:19 +0100765 f_upd_ptmsi_and_tlli(aa.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets);
Harald Welte04683d02018-02-16 22:43:45 +0100766 }
767 if (ispresent(aa.msIdentity)) {
768 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200769 mtc.stop;
Harald Welte04683d02018-02-16 22:43:45 +0100770 }
771 /* P-TMSI.sig */
772 if (ispresent(aa.ptmsiSignature)) {
773 g_pars.p_tmsi_sig := aa.ptmsiSignature.valueField;
774 }
775 /* updateTimer */
776 // aa.readyTimer
777 /* T3302, T3319, T3323, T3312_ext, T3324 */
778}
779
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200780function f_process_rau_accept(PDU_GMM_RoutingAreaUpdateAccept ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +0100781 /* mandatory IE */
782 g_pars.ra := ra.routingAreaId;
783 if (ispresent(ra.allocatedPTMSI)) {
784 if (not g_pars.net.expect_ptmsi) {
785 setverdict(fail, "unexpected P-TMSI allocation");
Daniel Willmannafce8662018-07-06 23:11:32 +0200786 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100787 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +0200788 f_upd_ptmsi_and_tlli(ra.allocatedPTMSI.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets, ran_index);
Harald Welte91636de2018-02-17 10:16:14 +0100789 }
790 if (ispresent(ra.msIdentity)) {
791 setverdict(fail, "unexpected TMSI allocation in non-combined attach");
Daniel Willmannafce8662018-07-06 23:11:32 +0200792 mtc.stop;
Harald Welte91636de2018-02-17 10:16:14 +0100793 }
794 /* P-TMSI.sig */
795 if (ispresent(ra.ptmsiSignature)) {
796 g_pars.p_tmsi_sig := ra.ptmsiSignature.valueField;
797 }
798 /* updateTimer */
799 // aa.readyTimer
800 /* T3302, T3319, T3323, T3312_ext, T3324 */
801}
802
803
Harald Welte5a4fa042018-02-16 20:59:21 +0100804function f_random_RAI(HEX0_3n mcc := '262'H, HEX0_3n mnc := '42'H) return RoutingAreaIdentificationV {
805 return f_RAI(mcc, mnc, f_rnd_octstring(2), f_rnd_octstring(1));
806}
807
Harald Welte23178c52018-02-17 09:36:33 +0100808/* return a MobileIdentityLV: P-TMSI if we have one, IMSI otherwise */
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700809private function f_mi_get_lv() runs on BSSGP_ConnHdlr return MobileIdentityLV {
Harald Welte23178c52018-02-17 09:36:33 +0100810 if (ispresent(g_pars.p_tmsi)) {
811 return valueof(ts_MI_TMSI_LV(g_pars.p_tmsi));
812 } else {
813 return valueof(ts_MI_IMSI_LV(g_pars.imsi));
814 }
815}
816
Harald Welte311ec272018-02-17 09:40:03 +0100817private function f_gmm_gsup_lu_isd() runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +0100818 var GSUP_PDU gsup;
Harald Welte311ec272018-02-17 09:40:03 +0100819 /* Expect MSC to perform LU with HLR */
820 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
Harald Welteeded9ad2018-02-17 20:57:34 +0100821 gsup := valueof(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
822 gsup.ies := gsup.ies & { valueof(ts_GSUP_IE_PdpInfo(char2oct("*"), '0121'O, ''O)) };
823 GSUP.send(gsup);
Harald Welte311ec272018-02-17 09:40:03 +0100824 GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
825 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
826}
827
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200828friend 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 +0100829 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200830 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 +0200831 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5ac31492018-02-15 20:39:13 +0100832
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200833 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
834 * 3G auth vectors */
835 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
836 /* The thing is, if the solSACapability is 'omit', then the
837 * revisionLevelIndicatior is at the wrong place! */
838 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
839
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200840 f_send_l3(attach_req, ran_index);
841 f_gmm_auth(umts_aka_challenge, force_gsm_sres, ran_index);
Alexander Couzens5844d5b2018-05-14 06:30:56 +0200842 /* Expect SGSN to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +0100843 f_gmm_gsup_lu_isd();
Harald Welte5ac31492018-02-15 20:39:13 +0100844
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200845 l3_mt := f_receive_l3(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?), ran_index);
Harald Welteca362462019-05-02 20:11:21 +0200846 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
847
Harald Welte04683d02018-02-16 22:43:45 +0100848 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200849 f_send_l3(ts_GMM_ATTACH_COMPL, ran_index);
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200850
851 /* IuPS case: Expect Iu Release */
Alexander Couzensb1ce1182019-09-15 22:43:40 +0200852 if (is_iu(ran_index)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200853 as_iu_release_compl_disc();
854 }
Alexander Couzens42d3cad2019-10-08 16:29:26 +0200855
856 /* Race condition
857 * It has shown, that GMM_ATTACH_COMPL might take some time to arrive at the SGSN through the layers.
858 * In TC hlr_location_cancel_request_update, the GMM_ATTACH_COMPL came 2ms too late, so that the Location Cancel Request
859 * arrived before it. This results in a test case failure.
860 * Delay execution by 50 ms
861 */
862 f_sleep(0.05);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200863}
864
Harald Weltef2f3c9b2020-06-17 22:11:43 +0200865friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
866 timer T := 5.0;
867 var PDU_BSSGP rx_pdu;
868 BSSGP_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
869 T.start;
870 alt {
871 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
872 return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
873 }
874 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, ?)) -> value rx_pdu {
875 setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
876 mtc.stop;
877 }
878 [] T.timeout {
879 setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
880 mtc.stop;
881 }
882 }
883 return '00'O;
884}
885
886friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
887 timer T := 5.0;
888 BSSGP_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id, susp_ref));
889 T.start;
890 alt {
891 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id));
892 [] BSSGP_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, g_pars.bssgp_cell_id[ran_idx].ra_id,
893?)) {
894 setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
895 mtc.stop;
896 }
897 [] T.timeout {
898 setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
899 mtc.stop;
900 }
901 }
902}
903
904
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200905private function f_TC_attach(charstring id) runs on BSSGP_ConnHdlr {
906 f_gmm_attach(false, false);
Harald Welte5a4fa042018-02-16 20:59:21 +0100907 setverdict(pass);
Harald Welte5ac31492018-02-15 20:39:13 +0100908}
909
910testcase TC_attach() runs on test_CT {
911 var BSSGP_ConnHdlr vc_conn;
912 f_init();
913 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200914 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1);
Harald Welte5ac31492018-02-15 20:39:13 +0100915 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200916 f_cleanup();
Harald Welte5ac31492018-02-15 20:39:13 +0100917}
918
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100919testcase TC_attach_mnc3() runs on test_CT {
920 var BSSGP_ConnHdlr vc_conn;
921 f_init('023042'H);
922 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200923 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, 1001);
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100924 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200925 f_cleanup();
Neels Hofmeyr8df7d152018-03-14 19:03:28 +0100926}
927
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200928private function f_TC_attach_umts_aka_umts_res(charstring id) runs on BSSGP_ConnHdlr {
929 f_gmm_attach(true, false);
930 setverdict(pass);
931}
932testcase TC_attach_umts_aka_umts_res() runs on test_CT {
933 var BSSGP_ConnHdlr vc_conn;
934 f_init();
935 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200936 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_umts_res), testcasename(), g_gb, 1002);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200937 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200938 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200939}
940
941private function f_TC_attach_umts_aka_gsm_sres(charstring id) runs on BSSGP_ConnHdlr {
942 f_gmm_attach(true, true);
943 setverdict(pass);
944}
945testcase TC_attach_umts_aka_gsm_sres() runs on test_CT {
946 var BSSGP_ConnHdlr vc_conn;
947 f_init();
948 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +0200949 vc_conn := f_start_handler(refers(f_TC_attach_umts_aka_gsm_sres), testcasename(), g_gb, 1003);
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200950 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200951 f_cleanup();
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +0200952}
953
Harald Welte5b7c8122018-02-16 21:48:17 +0100954/* MS never responds to ID REQ, expect ATTACH REJECT */
955private function f_TC_attach_auth_id_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100956 var RoutingAreaIdentificationV old_ra := f_random_RAI();
957
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200958 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100959 alt {
Harald Welte955aa942019-05-03 01:29:29 +0200960 [] BSSGP[0].receive(tr_GMM_ID_REQ(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100961 /* don't send ID Response */
962 repeat;
963 }
Harald Welte955aa942019-05-03 01:29:29 +0200964 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('09'O)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100965 setverdict(pass);
966 }
Harald Welte955aa942019-05-03 01:29:29 +0200967 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +0100968 setverdict(fail, "Wrong Attach Reject Cause");
Daniel Willmannafce8662018-07-06 23:11:32 +0200969 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +0100970 }
971 }
972}
973testcase TC_attach_auth_id_timeout() runs on test_CT {
974 var BSSGP_ConnHdlr vc_conn;
975 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200976 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 +0100977 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200978 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +0100979}
980
981/* HLR never responds to SAI REQ, expect ATTACH REJECT */
982private function f_TC_attach_auth_sai_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte5b7c8122018-02-16 21:48:17 +0100983 var RoutingAreaIdentificationV old_ra := f_random_RAI();
984
Alexander Couzens4444b5a2019-08-13 13:25:32 +0200985 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +0100986 alt {
987 [] as_mm_identity();
988 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); { }
989 }
990 /* don't send SAI-response from HLR */
Harald Welte955aa942019-05-03 01:29:29 +0200991 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Welte5b7c8122018-02-16 21:48:17 +0100992 setverdict(pass);
993}
994testcase TC_attach_auth_sai_timeout() runs on test_CT {
995 var BSSGP_ConnHdlr vc_conn;
996 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +0200997 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_timeout), testcasename(), g_gb, 3);
Harald Welte5b7c8122018-02-16 21:48:17 +0100998 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +0200999 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001000}
1001
Harald Weltefe253882018-02-17 09:25:00 +01001002/* HLR rejects SAI, expect ATTACH REJECT */
1003private function f_TC_attach_auth_sai_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Weltefe253882018-02-17 09:25:00 +01001004 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1005
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001006 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Weltefe253882018-02-17 09:25:00 +01001007 alt {
1008 [] as_mm_identity();
1009 [] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)); {
1010 GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 23));
1011 }
1012 }
Harald Welte955aa942019-05-03 01:29:29 +02001013 BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?));
Harald Weltefe253882018-02-17 09:25:00 +01001014 setverdict(pass);
1015}
1016testcase TC_attach_auth_sai_reject() runs on test_CT {
1017 var BSSGP_ConnHdlr vc_conn;
1018 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001019 vc_conn := f_start_handler(refers(f_TC_attach_auth_sai_reject), testcasename(), g_gb, 4);
Harald Weltefe253882018-02-17 09:25:00 +01001020 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001021 f_cleanup();
Harald Weltefe253882018-02-17 09:25:00 +01001022}
1023
Harald Welte5b7c8122018-02-16 21:48:17 +01001024/* HLR never responds to UL REQ, expect ATTACH REJECT */
1025private function f_TC_attach_gsup_lu_timeout(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001026 var PDU_L3_SGSN_MS l3_mt;
Harald Welte5b7c8122018-02-16 21:48:17 +01001027 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1028
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001029 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte5b7c8122018-02-16 21:48:17 +01001030 f_gmm_auth();
1031 /* Expect MSC to perform LU with HLR */
1032 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
1033 /* Never follow-up with ISD_REQ or UL_RES */
1034 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001035 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welte5b7c8122018-02-16 21:48:17 +01001036 setverdict(pass);
1037 }
Harald Welte955aa942019-05-03 01:29:29 +02001038 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1039 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte5b7c8122018-02-16 21:48:17 +01001040 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001041 mtc.stop;
Harald Welte5b7c8122018-02-16 21:48:17 +01001042 }
1043 }
1044}
1045testcase TC_attach_gsup_lu_timeout() runs on test_CT {
1046 var BSSGP_ConnHdlr vc_conn;
1047 f_init();
1048 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001049 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_timeout), testcasename(), g_gb, 5);
Harald Welte5b7c8122018-02-16 21:48:17 +01001050 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001051 f_cleanup();
Harald Welte5b7c8122018-02-16 21:48:17 +01001052}
1053
Harald Welteb7c14e92018-02-17 09:29:16 +01001054/* HLR rejects UL REQ, expect ATTACH REJECT */
1055private function f_TC_attach_gsup_lu_reject(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001056 var PDU_L3_SGSN_MS l3_mt;
Harald Welteb7c14e92018-02-17 09:29:16 +01001057 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1058
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001059 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb7c14e92018-02-17 09:29:16 +01001060 f_gmm_auth();
1061 /* Expect MSC to perform LU with HLR */
1062 GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi)) {
1063 GSUP.send(ts_GSUP_UL_ERR(g_pars.imsi, 0));
1064 }
1065 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001066 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb7c14e92018-02-17 09:29:16 +01001067 setverdict(pass);
1068 }
Harald Welte955aa942019-05-03 01:29:29 +02001069 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1070 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welteb7c14e92018-02-17 09:29:16 +01001071 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001072 mtc.stop;
Harald Welteb7c14e92018-02-17 09:29:16 +01001073 }
1074 }
1075}
1076testcase TC_attach_gsup_lu_reject() runs on test_CT {
1077 var BSSGP_ConnHdlr vc_conn;
1078 f_init();
1079 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001080 vc_conn := f_start_handler(refers(f_TC_attach_gsup_lu_reject), testcasename(), g_gb, 6);
Harald Welteb7c14e92018-02-17 09:29:16 +01001081 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001082 f_cleanup();
Harald Welteb7c14e92018-02-17 09:29:16 +01001083}
1084
1085
Harald Welte3823e2e2018-02-16 21:53:48 +01001086/* Attempt of combined GPRS + IMSI attach: network should ACK only GPRS attach */
1087private function f_TC_attach_combined(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001088 var PDU_L3_SGSN_MS l3_mt;
Harald Welte3823e2e2018-02-16 21:53:48 +01001089 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1090
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001091 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, true, false, omit, omit));
Harald Welte3823e2e2018-02-16 21:53:48 +01001092 f_gmm_auth();
1093 /* Expect MSC to perform LU with HLR */
Harald Welte311ec272018-02-17 09:40:03 +01001094 f_gmm_gsup_lu_isd();
Harald Welte3823e2e2018-02-16 21:53:48 +01001095
Harald Welte955aa942019-05-03 01:29:29 +02001096 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1097 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001098 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001099 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte3823e2e2018-02-16 21:53:48 +01001100 setverdict(pass);
1101}
Harald Welte3823e2e2018-02-16 21:53:48 +01001102testcase TC_attach_combined() runs on test_CT {
1103 var BSSGP_ConnHdlr vc_conn;
1104 f_init();
1105 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001106 vc_conn := f_start_handler(refers(f_TC_attach_combined), testcasename(), g_gb, 7);
Harald Welte3823e2e2018-02-16 21:53:48 +01001107 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001108 f_cleanup();
Harald Welte3823e2e2018-02-16 21:53:48 +01001109}
1110
Harald Welte76dee092018-02-16 22:12:59 +01001111/* Attempt of GPRS ATTACH in 'accept all' mode */
1112private function f_TC_attach_accept_all(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02001113 var PDU_L3_SGSN_MS l3_mt;
Harald Welte76dee092018-02-16 22:12:59 +01001114 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1115
1116 g_pars.net.expect_auth := false;
1117
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001118 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welte76dee092018-02-16 22:12:59 +01001119 f_gmm_auth();
Harald Welte955aa942019-05-03 01:29:29 +02001120 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
1121 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Harald Welte04683d02018-02-16 22:43:45 +01001122 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001123 f_send_l3(ts_GMM_ATTACH_COMPL);
Harald Welte76dee092018-02-16 22:12:59 +01001124 setverdict(pass);
1125}
1126testcase TC_attach_accept_all() runs on test_CT {
1127 var BSSGP_ConnHdlr vc_conn;
1128 f_init();
1129 f_sleep(1.0);
1130 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
Alexander Couzens51114d12018-07-31 18:41:56 +02001131 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 8);
Harald Welte76dee092018-02-16 22:12:59 +01001132 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001133 f_cleanup();
Harald Welte76dee092018-02-16 22:12:59 +01001134}
Harald Welte5b7c8122018-02-16 21:48:17 +01001135
Harald Welteb2124b22018-02-16 22:26:56 +01001136/* Attempt of GPRS ATTACH in 'accept all' mode */
1137private function f_TC_attach_closed_foreign(charstring id) runs on BSSGP_ConnHdlr {
Harald Welteb2124b22018-02-16 22:26:56 +01001138 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1139
1140 /* Simulate a foreign IMSI */
1141 g_pars.imsi := '001010123456789'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02001142 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Harald Welteb2124b22018-02-16 22:26:56 +01001143
1144 g_pars.net.expect_auth := false;
1145
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001146 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Harald Welteb2124b22018-02-16 22:26:56 +01001147 alt {
1148 [] as_mm_identity();
Harald Welte955aa942019-05-03 01:29:29 +02001149 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT('07'O)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001150 setverdict(pass);
1151 }
Harald Welte955aa942019-05-03 01:29:29 +02001152 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Harald Welteb2124b22018-02-16 22:26:56 +01001153 setverdict(pass);
1154 }
Harald Welte955aa942019-05-03 01:29:29 +02001155 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001156 setverdict(fail);
Daniel Willmannafce8662018-07-06 23:11:32 +02001157 mtc.stop;
Alexander Couzens0ca0d9c2018-06-12 14:01:34 +02001158 }
Harald Welteb2124b22018-02-16 22:26:56 +01001159 }
1160}
1161testcase TC_attach_closed() runs on test_CT {
1162 var BSSGP_ConnHdlr vc_conn;
1163 f_init();
1164 f_sleep(1.0);
1165 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
1166 /* test with foreign IMSI: Must Reject */
Alexander Couzens51114d12018-07-31 18:41:56 +02001167 vc_conn := f_start_handler(refers(f_TC_attach_closed_foreign), testcasename(), g_gb, 9);
Harald Welteb2124b22018-02-16 22:26:56 +01001168 vc_conn.done;
1169 /* test with home IMSI: Must Accept */
Alexander Couzens51114d12018-07-31 18:41:56 +02001170 vc_conn := f_start_handler(refers(f_TC_attach_accept_all), testcasename(), g_gb, 10);
Harald Welteb2124b22018-02-16 22:26:56 +01001171 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001172 f_cleanup();
Harald Welteb2124b22018-02-16 22:26:56 +01001173}
1174
Harald Welte04683d02018-02-16 22:43:45 +01001175/* Routing Area Update from Unknown TLLI -> REJECT */
1176private function f_TC_rau_unknown(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte04683d02018-02-16 22:43:45 +01001177 var RoutingAreaIdentificationV old_ra := f_random_RAI();
1178
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001179 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 +01001180 alt {
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01001181 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) { /* gmm cause: implicitly detached */
Harald Welte04683d02018-02-16 22:43:45 +01001182 setverdict(pass);
1183 }
1184 /* FIXME: Expect XID RESET? */
Alexander Couzens0e510e62018-07-28 23:06:00 +02001185 [] BSSGP[0].receive { repeat; }
Harald Welte04683d02018-02-16 22:43:45 +01001186 }
1187}
1188testcase TC_rau_unknown() runs on test_CT {
1189 var BSSGP_ConnHdlr vc_conn;
1190 f_init();
1191 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001192 vc_conn := f_start_handler(refers(f_TC_rau_unknown), testcasename(), g_gb, 11);
Harald Welte04683d02018-02-16 22:43:45 +01001193 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001194 f_cleanup();
Harald Welte04683d02018-02-16 22:43:45 +01001195}
1196
Harald Welte91636de2018-02-17 10:16:14 +01001197private function f_TC_attach_rau(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte91636de2018-02-17 10:16:14 +01001198 /* first perform regular attach */
1199 f_TC_attach(id);
1200
Alexander Couzens5dce90d2018-07-31 03:16:37 +02001201 f_routing_area_update(g_pars.ra);
1202
Harald Welte91636de2018-02-17 10:16:14 +01001203}
1204testcase TC_attach_rau() runs on test_CT {
1205 var BSSGP_ConnHdlr vc_conn;
1206 f_init();
1207 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001208 vc_conn := f_start_handler(refers(f_TC_attach_rau), testcasename(), g_gb, 12);
Harald Welte91636de2018-02-17 10:16:14 +01001209 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001210 f_cleanup();
Harald Welte91636de2018-02-17 10:16:14 +01001211}
Harald Welte04683d02018-02-16 22:43:45 +01001212
Harald Welte6abb9fe2018-02-17 15:24:48 +01001213/* general GPRS DETACH helper */
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001214function 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 +02001215 var PDU_L3_SGSN_MS l3_mt;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001216 timer T := 5.0;
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001217 f_send_l3(ts_GMM_DET_REQ_MO(detach_type, power_off), ran_index);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001218 if (expect_purge) {
1219 GSUP.receive(tr_GSUP_PURGE_MS_REQ(g_pars.imsi, OSMO_GSUP_CN_DOMAIN_PS));
1220 GSUP.send(ts_GSUP_PURGE_MS_RES(g_pars.imsi));
1221 }
1222 T.start;
1223 alt {
1224 [not expect_purge] GSUP.receive(tr_GSUP_PURGE_MS_REQ(?)) {
1225 setverdict(fail, "Unexpected GSUP PURGE MS for unregistered TLLI");
Daniel Willmannafce8662018-07-06 23:11:32 +02001226 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001227 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001228 [power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001229 g_pars.ra := omit;
Alexander Couzens8e0fd462019-05-11 01:20:55 +02001230 setverdict(fail, "Unexpected DETACH ACCEPT in power-off DETACH");
Daniel Willmannafce8662018-07-06 23:11:32 +02001231 mtc.stop;
Harald Welte6abb9fe2018-02-17 15:24:48 +01001232 /* TODO: check if any PDP contexts are deactivated on network side? */
1233 }
1234 [power_off] T.timeout {
1235 setverdict(pass);
1236 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001237 [not power_off] BSSGP[ran_index].receive(tr_GMM_DET_ACCEPT_MT) -> value l3_mt {
Harald Welte6abb9fe2018-02-17 15:24:48 +01001238 g_pars.ra := omit;
1239 setverdict(pass);
1240 /* TODO: check if any PDP contexts are deactivated on network side? */
1241 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001242 [] BSSGP[ran_index].receive(PDU_L3_SGSN_MS:?) -> value l3_mt {
Alexander Couzens4630e742019-05-11 01:50:10 +02001243 if (power_off) {
1244 setverdict(fail, "Unexpected Layer 3 package received in power-off DETACH");
1245 } else {
1246 setverdict(fail, "Unexpected Layer 3 package received in normal DETACH");
1247 }
1248 mtc.stop;
1249 }
Alexander Couzensb22e8ce2019-09-15 22:39:58 +02001250 [] BSSGP[ran_index].receive { repeat; }
Harald Welte6abb9fe2018-02-17 15:24:48 +01001251 }
1252}
1253
1254/* IMSI DETACH (non-power-off) for unknown TLLI */
1255private function f_TC_detach_unknown_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1256 f_detach_mo(c_GMM_DTT_MO_GPRS, false, false);
1257}
1258testcase TC_detach_unknown_nopoweroff() runs on test_CT {
1259 var BSSGP_ConnHdlr vc_conn;
1260 f_init();
1261 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001262 vc_conn := f_start_handler(refers(f_TC_detach_unknown_nopoweroff), testcasename(), g_gb, 13);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001263 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001264 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001265}
1266
1267/* IMSI DETACH (power-off) for unknown TLLI */
1268private function f_TC_detach_unknown_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1269 f_detach_mo(c_GMM_DTT_MO_GPRS, true, false);
1270}
1271testcase TC_detach_unknown_poweroff() runs on test_CT {
1272 var BSSGP_ConnHdlr vc_conn;
1273 f_init();
1274 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001275 vc_conn := f_start_handler(refers(f_TC_detach_unknown_poweroff), testcasename(), g_gb, 14);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001276 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001277 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001278}
1279
1280/* IMSI DETACH (non-power-off) for known TLLI */
1281private function f_TC_detach_nopoweroff(charstring id) runs on BSSGP_ConnHdlr {
1282 /* first perform regular attach */
1283 f_TC_attach(id);
1284
1285 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
1286}
1287testcase TC_detach_nopoweroff() runs on test_CT {
1288 var BSSGP_ConnHdlr vc_conn;
1289 f_init();
1290 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001291 vc_conn := f_start_handler(refers(f_TC_detach_nopoweroff), testcasename(), g_gb, 15);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001292 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001293 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001294}
1295
1296/* IMSI DETACH (power-off) for known TLLI */
1297private function f_TC_detach_poweroff(charstring id) runs on BSSGP_ConnHdlr {
1298 /* first perform regular attach */
1299 f_TC_attach(id);
1300
1301 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
1302}
1303testcase TC_detach_poweroff() runs on test_CT {
1304 var BSSGP_ConnHdlr vc_conn;
1305 f_init();
1306 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001307 vc_conn := f_start_handler(refers(f_TC_detach_poweroff), testcasename(), g_gb, 16);
Harald Welte6abb9fe2018-02-17 15:24:48 +01001308 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001309 f_cleanup();
Harald Welte6abb9fe2018-02-17 15:24:48 +01001310}
1311
Harald Welteeded9ad2018-02-17 20:57:34 +01001312type record PdpActPars {
Harald Welte822f9102018-02-18 20:39:06 +01001313 BIT3 tid, /* L3 Transaction ID */
1314 BIT4 nsapi, /* SNDCP NSAPI */
1315 BIT4 sapi, /* LLC SAPI */
1316 QoSV qos, /* QoS parameters */
1317 PDPAddressV addr, /* IP address */
1318 octetstring apn optional, /* APN name */
1319 ProtocolConfigOptionsV pco optional, /* protoco config opts */
1320 OCT1 exp_rej_cause optional, /* expected SM reject cause */
Harald Welte1d6ae932018-02-18 21:24:44 +01001321 OCT1 gtp_resp_cause, /* GTP response cause */
Harald Welte822f9102018-02-18 20:39:06 +01001322 OCT4 chg_id, /* GTP Charging Identifier */
Harald Welte6abb9fe2018-02-17 15:24:48 +01001323
Harald Welte822f9102018-02-18 20:39:06 +01001324 OCT4 ggsn_tei_c, /* GGSN TEI Control*/
1325 OCT4 ggsn_tei_u, /* GGSN TEI User */
1326 octetstring ggsn_ip_c, /* GGSN IP Control */
1327 octetstring ggsn_ip_u, /* GGSN IP User */
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001328 OCT1 ggsn_restart_ctr, /* GGSN Restart Counter */
Harald Welteeded9ad2018-02-17 20:57:34 +01001329
Harald Welte822f9102018-02-18 20:39:06 +01001330 OCT4 sgsn_tei_c optional, /* SGSN TEI Control */
1331 OCT4 sgsn_tei_u optional, /* SGSN TEI User */
1332 octetstring sgsn_ip_c optional, /* SGSN IP Control */
1333 octetstring sgsn_ip_u optional /* SGSN IP USer */
Harald Welteeded9ad2018-02-17 20:57:34 +01001334};
1335
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001336
1337private function f_process_gtp_ctx_act_req(inout PdpActPars apars, PDU_GTPC gtpc) runs on BSSGP_ConnHdlr {
1338 var GTPC_PDUs gtpc_rx := gtpc.gtpc_pdu;
1339 apars.sgsn_tei_c := gtpc_rx.createPDPContextRequest.teidControlPlane.teidControlPlane;
1340 apars.sgsn_tei_u := gtpc_rx.createPDPContextRequest.teidDataI.teidDataI;
1341 apars.sgsn_ip_c := gtpc_rx.createPDPContextRequest.sgsn_addr_signalling.addressf;
1342 apars.sgsn_ip_u := gtpc_rx.createPDPContextRequest.sgsn_addr_traffic.addressf;
1343 f_gtp_register_teid(apars.ggsn_tei_c);
1344 f_gtp_register_teid(apars.ggsn_tei_u);
1345}
1346
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001347function f_pdp_ctx_act(inout PdpActPars apars, boolean send_recovery := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001348runs on BSSGP_ConnHdlr {
Harald Welteeded9ad2018-02-17 20:57:34 +01001349 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1350 var Gtp1cUnitdata g_ud;
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001351 var template Recovery_gtpc recovery := omit;
1352
1353 if (send_recovery) {
1354 recovery := ts_Recovery(apars.ggsn_restart_ctr);
1355 }
Harald Welteeded9ad2018-02-17 20:57:34 +01001356
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001357 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 +02001358 apars.apn, apars.pco), ran_index);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001359 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud {
1360 f_process_gtp_ctx_act_req(apars, g_ud.gtpc);
1361 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1362 GTP.send(ts_GTPC_CreatePdpResp(g_ud.peer, seq_nr,
1363 apars.sgsn_tei_c, apars.gtp_resp_cause,
1364 apars.ggsn_tei_c, apars.ggsn_tei_u,
1365 apars.nsapi,
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001366 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
1367 omit, recovery));
Harald Welteeded9ad2018-02-17 20:57:34 +01001368 }
1369 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001370 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, apars.exp_rej_cause)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001371 setverdict(pass);
1372 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001373 [exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001374 setverdict(fail, "Unexpected PDP CTX ACT ACC");
Daniel Willmannafce8662018-07-06 23:11:32 +02001375 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001376 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001377 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001378 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
Daniel Willmannafce8662018-07-06 23:11:32 +02001379 mtc.stop;
Harald Welteeded9ad2018-02-17 20:57:34 +01001380 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001381 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_REJ(apars.tid, ?)) {
Harald Weltef7191672019-05-02 20:37:23 +02001382 setverdict(fail, "Unexpected PDP CTX ACT FAIL");
1383 mtc.stop;
1384 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001385 [not exp_rej] BSSGP[ran_index].receive(tr_SM_ACT_PDP_ACCEPT(apars.tid, apars.sapi)) {
Harald Welteeded9ad2018-02-17 20:57:34 +01001386 setverdict(pass);
1387 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001388 [] as_xid(apars, ran_index);
Harald Welteeded9ad2018-02-17 20:57:34 +01001389 }
1390}
1391
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001392function f_pdp_ctx_deact_mo(inout PdpActPars apars, OCT1 cause, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001393runs on BSSGP_ConnHdlr {
Harald Welte6f203162018-02-18 22:04:55 +01001394 var boolean exp_rej := ispresent(apars.exp_rej_cause);
1395 var Gtp1cUnitdata g_ud;
1396
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001397 f_send_l3(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause, false, omit), ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001398 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1399 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001400 BSSGP[ran_index].clear;
Harald Welte6f203162018-02-18 22:04:55 +01001401 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1402 }
1403 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001404 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Harald Welte6f203162018-02-18 22:04:55 +01001405 setverdict(pass);
1406 }
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001407 [] as_xid(apars, ran_index);
Harald Welte6f203162018-02-18 22:04:55 +01001408 }
1409}
1410
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001411function f_pdp_ctx_deact_mt(inout PdpActPars apars, boolean error_ind := false, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001412runs on BSSGP_ConnHdlr {
Harald Welte57b9b7f2018-02-18 22:28:13 +01001413 var Gtp1cUnitdata g_ud;
1414 var integer seq_nr := 23;
1415 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1416
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001417 BSSGP[ran_index].clear;
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001418 if (error_ind) {
1419 GTP.send(ts_GTPU_ErrorIndication(peer, 0 /* seq */, apars.ggsn_tei_u, apars.ggsn_ip_u));
1420 } else {
1421 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1422 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001423
1424 timer T := 5.0;
1425 T.start;
1426
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001427 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001428 [] BSSGP[ran_index].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1429 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), ran_index);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001430 }
Alexander Couzens5e71c142018-08-07 17:21:24 +02001431 [not error_ind] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {
1432 repeat;
1433 }
1434 [] T.timeout {
1435 setverdict(fail, "Waiting for SM_DEACT_PDP_REQ_MT");
1436 }
Harald Welte57b9b7f2018-02-18 22:28:13 +01001437 }
1438}
1439
Harald Welte6f203162018-02-18 22:04:55 +01001440
Harald Welteeded9ad2018-02-17 20:57:34 +01001441/* Table 10.5.156/3GPP TS 24.008 */
1442template (value) QoSV t_QosDefault := {
1443 reliabilityClass := '011'B, /* unacknowledged GTP+LLC, acknowledged RLC */
1444 delayClass := '100'B, /* best effort */
1445 spare1 := '00'B,
1446 precedenceClass := '010'B, /* normal */
1447 spare2 := '0'B,
1448 peakThroughput := '0000'B, /* subscribed */
1449 meanThroughput := '00000'B, /* subscribed */
1450 spare3 := '000'B,
1451 deliverErroneusSDU := omit,
1452 deliveryOrder := omit,
1453 trafficClass := omit,
1454 maxSDUSize := omit,
1455 maxBitrateUplink := omit,
1456 maxBitrateDownlink := omit,
1457 sduErrorRatio := omit,
1458 residualBER := omit,
1459 trafficHandlingPriority := omit,
1460 transferDelay := omit,
1461 guaranteedBitRateUplink := omit,
1462 guaranteedBitRateDownlink := omit,
1463 sourceStatisticsDescriptor := omit,
1464 signallingIndication := omit,
1465 spare4 := omit,
1466 maxBitrateDownlinkExt := omit,
1467 guaranteedBitRateDownlinkExt := omit,
1468 maxBitrateUplinkExt := omit,
1469 guaranteedBitRateUplinkExt := omit,
1470 maxBitrateDownlinkExt2 := omit,
1471 guaranteedBitRateDownlinkExt2 := omit,
1472 maxBitrateUplinkExt2 := omit,
1473 guaranteedBitRateUplinkExt2 := omit
1474}
1475
1476/* 10.5.6.4 / 3GPP TS 24.008 */
1477template (value) PDPAddressV t_AddrIPv4dyn := {
1478 pdpTypeOrg := '0001'B, /* IETF */
1479 spare := '0000'B,
1480 pdpTypeNum := '21'O, /* IPv4 */
1481 addressInfo := omit
1482}
1483template (value) PDPAddressV t_AddrIPv6dyn := {
1484 pdpTypeOrg := '0001'B, /* IETF */
1485 spare := '0000'B,
1486 pdpTypeNum := '53'O, /* IPv6 */
1487 addressInfo := omit
1488}
1489
Harald Welte37692d82018-02-18 15:21:34 +01001490template (value) PdpActPars t_PdpActPars(charstring ggsn_ip) := {
Harald Welteeded9ad2018-02-17 20:57:34 +01001491 tid := '000'B,
1492 nsapi := '0101'B, /* < 5 are reserved */
1493 sapi := '0011'B, /* 3/5/9/11 */
1494 qos := t_QosDefault,
1495 addr := t_AddrIPv4dyn,
1496 apn := omit,
1497 pco := omit,
1498 exp_rej_cause := omit,
Harald Welte1d6ae932018-02-18 21:24:44 +01001499 gtp_resp_cause := int2oct(128, 1),
1500 chg_id := f_rnd_octstring(4),
Harald Welteeded9ad2018-02-17 20:57:34 +01001501
1502 /* FIXME: make below dynamic !! */
Harald Welte1d6ae932018-02-18 21:24:44 +01001503 ggsn_tei_c := f_rnd_octstring(4),
1504 ggsn_tei_u := f_rnd_octstring(4),
Harald Welte37692d82018-02-18 15:21:34 +01001505 ggsn_ip_c := f_inet_addr(ggsn_ip),
1506 ggsn_ip_u := f_inet_addr(ggsn_ip),
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001507 ggsn_restart_ctr := int2oct(2, 1),
Harald Welteeded9ad2018-02-17 20:57:34 +01001508
Harald Welteeded9ad2018-02-17 20:57:34 +01001509 sgsn_tei_c := omit,
Harald Weltef8af5d62018-02-18 15:06:42 +01001510 sgsn_tei_u := omit,
1511 sgsn_ip_c := omit,
1512 sgsn_ip_u := omit
Harald Welteeded9ad2018-02-17 20:57:34 +01001513}
1514
Harald Welte37692d82018-02-18 15:21:34 +01001515template (value) GtpPeer ts_GtpPeerU(octetstring ip) := {
1516 connId := 1,
1517 remName := f_inet_ntoa(ip),
1518 remPort := GTP1U_PORT
1519}
1520
1521template (value) GtpPeer ts_GtpPeerC(octetstring ip) := {
1522 connId := 1,
1523 remName := f_inet_ntoa(ip),
1524 remPort := GTP1C_PORT
1525}
1526
1527private function f_gtpu_send(inout PdpActPars apars, octetstring payload) runs on BSSGP_ConnHdlr {
1528 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1529 GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, apars.sgsn_tei_u, payload));
1530}
1531
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001532private altstep as_xid(PdpActPars apars, integer ran_index := 0) runs on BSSGP_ConnHdlr {
1533 [] BSSGP[ran_index].receive(tr_LLC_XID_MT_CMD(?, apars.sapi)) {
Harald Welte37692d82018-02-18 15:21:34 +01001534 repeat;
1535 }
1536}
1537
1538template PDU_SN tr_SN_UD(template BIT4 nsapi, template octetstring payload) := {
1539 pDU_SN_UNITDATA := {
1540 nsapi := nsapi,
1541 moreBit := ?,
1542 snPduType := '1'B,
1543 firstSegmentIndicator := ?,
1544 spareBit := ?,
1545 pcomp := ?,
1546 dcomp := ?,
1547 npduNumber := ?,
1548 segmentNumber := ?,
1549 npduNumberContinued := ?,
1550 dataSegmentSnUnitdataPdu := payload
1551 }
1552}
1553
1554/* simple case: single segment, no compression */
1555template (value) PDU_SN ts_SN_UD(BIT4 nsapi, octetstring payload) := {
1556 pDU_SN_UNITDATA := {
1557 nsapi := nsapi,
1558 moreBit := '0'B,
1559 snPduType := '1'B,
1560 firstSegmentIndicator := '1'B,
1561 spareBit := '0'B,
1562 pcomp := '0000'B,
1563 dcomp := '0000'B,
1564 npduNumber := '0000'B,
1565 segmentNumber := '0000'B,
1566 npduNumberContinued := '00'O,
1567 dataSegmentSnUnitdataPdu := payload
1568 }
1569}
1570
1571/* Transceive given 'payload' as MT message from GTP -> OsmoSGSN -> Gb */
Harald Weltea5c71cd2020-06-17 22:12:04 +02001572private 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 +02001573runs on BSSGP_ConnHdlr {
Harald Weltea5c71cd2020-06-17 22:12:04 +02001574 timer T := 5.0;
Harald Welte37692d82018-02-18 15:21:34 +01001575 /* Send PDU via GTP from our simulated GGSN to the SGSN */
1576 f_gtpu_send(apars, payload);
Harald Weltea5c71cd2020-06-17 22:12:04 +02001577 T.start;
Harald Welte37692d82018-02-18 15:21:34 +01001578 /* Expect PDU via BSSGP/LLC on simulated PCU from SGSN */
1579 alt {
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001580 [] as_xid(apars, ran_index);
1581 //[] BSSGP[ran_index].receive(tr_BD_SNDCP(apars.sapi, tr_SN_UD(apars.nsapi, payload)));
Harald Weltea5c71cd2020-06-17 22:12:04 +02001582 [expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload));
1583 [expect_fwd] T.timeout {
1584 setverdict(fail, "Timeout waiting for GTP-U to appear on BSSGP");
1585 mtc.stop;
1586 }
1587 [not expect_fwd] BSSGP[ran_index].receive(tr_SN_UD(apars.nsapi, payload)) {
1588 setverdict(fail, "GTP-U forwarded to BSSGP but not expected")
1589 mtc.stop;
1590 }
1591 [not expect_fwd] T.timeout {}
Harald Welte37692d82018-02-18 15:21:34 +01001592 }
1593}
1594
Harald Welte64d6b512020-06-17 16:42:00 +02001595/* Transceive given 'payload' as MO message from Gb -> OsmoSGSN -> GTP */
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001596private function f_gtpu_xceive_mo(inout PdpActPars apars, octetstring payload, integer ran_index := 0)
Harald Weltef7191672019-05-02 20:37:23 +02001597runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001598 /* Send PDU via SNDCP/LLC/BSSGP/NS via simulated MS/PCU to the SGSN */
1599 var GtpPeer peer := valueof(ts_GtpPeerU(apars.sgsn_ip_u));
1600 var PDU_SN sndcp := valueof(ts_SN_UD(apars.nsapi, payload));
Alexander Couzensb1ce1182019-09-15 22:43:40 +02001601 BSSGP[ran_index].send(ts_LLC_UI(enc_PDU_SN(sndcp), apars.sapi, '0'B, 0));
Harald Welte37692d82018-02-18 15:21:34 +01001602 /* Expect PDU via GTP from SGSN on simulated GGSN */
1603 alt {
1604 [] GTP.receive(tr_GTPU_GPDU(peer, apars.ggsn_tei_u, payload));
1605 }
1606}
1607
Harald Welteeded9ad2018-02-17 20:57:34 +01001608private function f_TC_attach_pdp_act(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001609 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Harald Welteeded9ad2018-02-17 20:57:34 +01001610
1611 /* first perform regular attach */
1612 f_TC_attach(id);
1613
1614 f_pdp_ctx_act(apars);
1615}
1616testcase TC_attach_pdp_act() runs on test_CT {
1617 var BSSGP_ConnHdlr vc_conn;
1618 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001619 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act), testcasename(), g_gb, 17);
Harald Welteeded9ad2018-02-17 20:57:34 +01001620 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001621 f_cleanup();
Harald Welteeded9ad2018-02-17 20:57:34 +01001622}
Harald Welteb2124b22018-02-16 22:26:56 +01001623
Harald Welte835b15f2018-02-18 14:39:11 +01001624/* PDP Context activation for not-attached subscriber; expect fail */
1625private function f_TC_pdp_act_unattached(charstring id) runs on BSSGP_ConnHdlr {
Harald Welte37692d82018-02-18 15:21:34 +01001626 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001627 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 +01001628 apars.apn, apars.pco));
1629 alt {
1630 /* We might want toalso actually expect a PDPC CTX ACT REJ? */
Harald Welte955aa942019-05-03 01:29:29 +02001631 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001632 setverdict(pass);
1633 }
1634 [] GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) {
1635 setverdict(fail, "Unexpected GTP PDP CTX ACT");
Daniel Willmannafce8662018-07-06 23:11:32 +02001636 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001637 }
Harald Welte955aa942019-05-03 01:29:29 +02001638 [] BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT(?, ?)) {
Harald Welte835b15f2018-02-18 14:39:11 +01001639 setverdict(fail, "Unexpected SM PDP CTX ACT ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +02001640 mtc.stop;
Harald Welte835b15f2018-02-18 14:39:11 +01001641 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02001642 [] BSSGP[0].receive { repeat; }
Harald Welte835b15f2018-02-18 14:39:11 +01001643 }
1644}
1645testcase TC_pdp_act_unattached() runs on test_CT {
1646 var BSSGP_ConnHdlr vc_conn;
1647 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001648 vc_conn := f_start_handler(refers(f_TC_pdp_act_unattached), testcasename(), g_gb, 18);
Harald Welte835b15f2018-02-18 14:39:11 +01001649 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001650 f_cleanup();
Harald Welte835b15f2018-02-18 14:39:11 +01001651}
1652
Harald Welte37692d82018-02-18 15:21:34 +01001653/* ATTACH + PDP CTX ACT + user plane traffic */
1654private function f_TC_attach_pdp_act_user(charstring id) runs on BSSGP_ConnHdlr {
1655 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1656
1657 /* first perform regular attach */
1658 f_TC_attach(id);
1659 /* then activate PDP context */
1660 f_pdp_ctx_act(apars);
1661 /* then transceive a downlink PDU */
1662 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1663 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1664}
1665testcase TC_attach_pdp_act_user() runs on test_CT {
1666 var BSSGP_ConnHdlr vc_conn;
1667 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001668 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_user), testcasename(), g_gb, 19);
Harald Welte37692d82018-02-18 15:21:34 +01001669 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001670 f_cleanup();
Harald Welte37692d82018-02-18 15:21:34 +01001671}
1672
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001673/* ATTACH + PDP CTX ACT; reject from GGSN */
1674private function f_TC_attach_pdp_act_ggsn_reject(charstring id) runs on BSSGP_ConnHdlr {
1675 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1676
1677 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1678 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1679
1680 /* first perform regular attach */
1681 f_TC_attach(id);
1682 /* then activate PDP context */
1683 f_pdp_ctx_act(apars);
1684}
1685testcase TC_attach_pdp_act_ggsn_reject() runs on test_CT {
1686 var BSSGP_ConnHdlr vc_conn;
1687 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001688 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_ggsn_reject), testcasename(), g_gb, 20);
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001689 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001690 f_cleanup();
Harald Welte5b5ca1b2018-02-18 21:25:03 +01001691}
Harald Welte835b15f2018-02-18 14:39:11 +01001692
Harald Welte6f203162018-02-18 22:04:55 +01001693/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MO direction */
1694private function f_TC_attach_pdp_act_user_deact_mo(charstring id) runs on BSSGP_ConnHdlr {
1695 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1696
1697 /* first perform regular attach */
1698 f_TC_attach(id);
1699 /* then activate PDP context */
1700 f_pdp_ctx_act(apars);
1701 /* then transceive a downlink PDU */
1702 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1703 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1704
1705 f_pdp_ctx_deact_mo(apars, '00'O);
1706}
1707testcase TC_attach_pdp_act_user_deact_mo() runs on test_CT {
1708 var BSSGP_ConnHdlr vc_conn;
1709 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001710 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 +01001711 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001712 f_cleanup();
Harald Welte6f203162018-02-18 22:04:55 +01001713}
1714
Harald Welte57b9b7f2018-02-18 22:28:13 +01001715/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction */
1716private function f_TC_attach_pdp_act_user_deact_mt(charstring id) runs on BSSGP_ConnHdlr {
1717 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1718
1719 /* first perform regular attach */
1720 f_TC_attach(id);
1721 /* then activate PDP context */
1722 f_pdp_ctx_act(apars);
1723 /* then transceive a downlink PDU */
1724 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
1725 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
1726
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02001727 f_pdp_ctx_deact_mt(apars, false);
Harald Welte57b9b7f2018-02-18 22:28:13 +01001728}
1729testcase TC_attach_pdp_act_user_deact_mt() runs on test_CT {
1730 var BSSGP_ConnHdlr vc_conn;
1731 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001732 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 +01001733 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001734 f_cleanup();
Harald Welte57b9b7f2018-02-18 22:28:13 +01001735}
1736
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001737/* Test MS sending a duplicate Deact PDP Ctx (OS#3956). */
1738private function f_TC_attach_pdp_act_deact_dup(charstring id) runs on BSSGP_ConnHdlr {
1739 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1740 var Gtp1cUnitdata g_ud;
1741 var integer i;
1742 var OCT1 cause_regular_deact := '24'O;
1743
1744 /* first perform regular attach + PDP context act */
1745 f_TC_attach(id);
1746 f_pdp_ctx_act(apars);
1747
1748 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1749 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, cause_regular_deact, false, omit), 0);
1750
1751 for (i := 0; i < 2; i := i+1) {
1752 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1753 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1754 log("Received deletePDPContextResponse " & int2str(i) & ", seq_nr=" & int2str(seq_nr));
1755 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1756 }
1757 }
1758
1759 alt {
1760 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1761 setverdict(pass);
1762 }
1763 [] as_xid(apars, 0);
1764 }
1765
1766 /* Make sure second DeactPdpAccept is sent: */
1767 timer T := 2.0;
1768 T.start;
1769 alt {
1770 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
1771 setverdict(fail, "Second SM_DEACT_PDP_ACCEPT_MT received");
1772 }
1773 [] T.timeout {
1774 setverdict(pass);
1775 }
1776 }
1777
1778 setverdict(pass);
1779}
1780testcase TC_attach_pdp_act_deact_dup() runs on test_CT {
1781 var BSSGP_ConnHdlr vc_conn;
1782 f_init();
1783 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_dup), testcasename(), g_gb, 46);
1784 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001785 f_cleanup();
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02001786}
1787
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001788/* ATTACH + ATTACH (2nd) */
1789private function f_TC_attach_forget_tlli_attach(charstring id) runs on BSSGP_ConnHdlr {
1790 g_pars.t_guard := 5.0;
1791
1792 /* first perform regular attach */
1793 f_TC_attach(id);
1794
1795 /* second to perform regular attach */
1796 f_TC_attach(id);
1797}
1798
1799
1800testcase TC_attach_second_attempt() runs on test_CT {
1801 var BSSGP_ConnHdlr vc_conn;
1802 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001803 vc_conn := f_start_handler(refers(f_TC_attach_forget_tlli_attach), testcasename(), g_gb, 22);
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001804 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001805 f_cleanup();
Alexander Couzens187ad5d2018-05-02 19:31:10 +02001806}
Harald Welte57b9b7f2018-02-18 22:28:13 +01001807
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001808private function f_TC_attach_echo_timeout(charstring id) runs on BSSGP_ConnHdlr {
1809 var Gtp1cUnitdata g_ud;
1810 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1811 var integer seq_nr;
1812
1813 /* first perform regular attach */
1814 f_TC_attach(id);
1815 /* then activate PDP context */
1816 f_pdp_ctx_act(apars);
1817
1818 /* Wait to receive first echo request and send initial Restart counter */
1819 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1820 BSSGP[0].clear;
1821 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1822 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1823 f_sleep(int2float(mp_echo_interval)); /* wait until around next echo is expected */
1824 }
1825
1826 /* At some point next echo request not answered will timeout and SGSN
1827 should drop the pdp ctx. Around T3 (3secs) * 6 (+ extra, a lot due to OS#4178): */
1828 timer T := 3.0 * 6.0 + 16.0;
1829 T.start;
1830 alt {
1831 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
1832 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
1833 setverdict(pass);
1834 }
1835 [] GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud {
1836 /* SGSN currently doesn't send this message because it expects GGSN to be non-reachable anyway */
1837 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1838 log("Received deletePDPContextRequest seq_nr=" & int2str(seq_nr));
1839 GTP.send(ts_GTPC_DeletePdpResp(g_ud.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
1840 repeat;
1841 }
1842 [] GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1843 seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1844 log("Received EchoRequest seq_nr=" & int2str(seq_nr));
1845 repeat;
1846 }
1847 [] T.timeout {
1848 setverdict(fail, "BSSGP DeactPdpReq not received");
1849 mtc.stop;
1850 }
1851 [] as_xid(apars);
1852 }
1853 T.stop
1854
1855 setverdict(pass);
1856}
1857/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1858testcase TC_attach_echo_timeout() runs on test_CT {
1859 var BSSGP_ConnHdlr vc_conn;
1860 g_use_echo := true;
1861 f_init();
1862 vc_conn := f_start_handler(refers(f_TC_attach_echo_timeout), testcasename(), g_gb, 67, 50.0);
1863 vc_conn.done;
1864 g_use_echo := false;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001865 f_cleanup();
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02001866}
1867
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001868private function f_TC_attach_restart_ctr_echo(charstring id) runs on BSSGP_ConnHdlr {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001869 var Gtp1cUnitdata g_ud;
1870 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1871
1872 /* first perform regular attach */
1873 f_TC_attach(id);
1874 /* Activate a pdp context against the GGSN */
1875 f_pdp_ctx_act(apars);
1876 /* Wait to receive first echo request and send initial Restart counter */
1877 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1878 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1879 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1880 }
1881 /* Wait to receive second echo request and send incremented Restart
1882 counter. This will fake a restarted GGSN, and pdp ctx allocated
1883 should be released by SGSN */
1884 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1885 GTP.receive(tr_GTPC_MsgType(?, echoRequest, ?)) -> value g_ud {
1886 var integer seq_nr := oct2int(g_ud.gtpc.opt_part.sequenceNumber);
1887 GTP.send(ts_GTPC_PONG(g_ud.peer, seq_nr, apars.ggsn_restart_ctr));
1888 }
1889 var OCT1 cause_network_failure := int2oct(38, 1)
1890 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001891 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, cause_network_failure, true)) {
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001892 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001893 setverdict(pass);
1894 }
1895 [] as_xid(apars);
1896 }
1897 setverdict(pass);
1898}
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001899/* ATTACH + trigger Recovery procedure through EchoResp */
1900testcase TC_attach_restart_ctr_echo() runs on test_CT {
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001901 var BSSGP_ConnHdlr vc_conn;
1902 g_use_echo := true
1903 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001904 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 +02001905 vc_conn.done;
1906 g_use_echo := false
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001907 f_cleanup();
Pau Espin Pedroldc27e482018-07-10 14:02:49 +02001908}
1909
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001910private function f_TC_attach_restart_ctr_create(charstring id) runs on BSSGP_ConnHdlr {
1911 var Gtp1cUnitdata g_ud;
1912 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1913 var integer seq_nr := 23;
1914 var GtpPeer peer;
1915 /* first perform regular attach */
1916 f_TC_attach(id);
1917
1918 /* Use this CTX ACT to send initial Restart counter to SGSN. */
1919 apars.gtp_resp_cause := int2oct(199, 1); /* no resources available */
1920 apars.exp_rej_cause := '1a'O; /* insufficient resources */
1921 f_pdp_ctx_act(apars, true);
1922
1923 /* Increment restart_ctr. This will fake a restarted GGSN when CreatePdpResp is
1924/* received. */
1925 apars.ggsn_restart_ctr := int2oct(oct2int(apars.ggsn_restart_ctr) + 1, 1);
1926
1927 /* FIXME: Once we can easily handle different pdp ctx simultaneously, it
1928 would be great to have an active pdp context here before triggering
1929 Recovery, and making sure the the DEACT request is sent by the SGSN.
1930 */
1931
1932 /* Activate a pdp context against the GGSN, send incremented Recovery
1933 IE. This should trigger the recovery path, but still this specific
1934 CTX activation should work. */
1935 apars.exp_rej_cause := omit; /* default value for tests */
1936 apars.gtp_resp_cause := int2oct(128, 1); /* default value for tests */
1937 f_pdp_ctx_act(apars, true);
1938
1939 setverdict(pass);
1940}
1941/* ATTACH + trigger Recovery procedure through CreatePdpResp */
1942testcase TC_attach_restart_ctr_create() runs on test_CT {
1943 var BSSGP_ConnHdlr vc_conn;
1944 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02001945 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 +02001946 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001947 f_cleanup();
Pau Espin Pedrol94013452018-07-17 15:50:21 +02001948}
1949
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001950/* ATTACH + PDP CTX ACT + user plane traffic + PDP CTX DEACT in MT direction + trigger T3395 */
1951private function f_TC_attach_pdp_act_deact_mt_t3395_expire(charstring id) runs on BSSGP_ConnHdlr {
1952 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1953 var integer seq_nr := 23;
1954 var GtpPeer peer;
1955 var integer i;
1956
1957 /* first perform regular attach */
1958 f_TC_attach(id);
1959 /* then activate PDP context */
1960 f_pdp_ctx_act(apars);
1961
Alexander Couzens0e510e62018-07-28 23:06:00 +02001962 BSSGP[0].clear;
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001963 peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
1964 GTP.send(ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B));
1965
1966 for (i := 0; i < 5; i := i+1) {
1967 alt {
Harald Welte955aa942019-05-03 01:29:29 +02001968 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {}
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001969 [] as_xid(apars);
1970 }
1971 }
1972
1973 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) {}
1974
Alexander Couzens4444b5a2019-08-13 13:25:32 +02001975 f_send_l3(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid));
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001976 setverdict(pass);
1977}
1978testcase TC_attach_pdp_act_deact_mt_t3395_expire() runs on test_CT {
1979 var BSSGP_ConnHdlr vc_conn;
1980 f_init();
1981 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02001982 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 +02001983 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02001984 f_cleanup();
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02001985}
1986
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02001987/* ATTACH + PDP CTX ACT dropped + retrans */
1988private function f_TC_attach_pdp_act_deact_gtp_retrans(charstring id) runs on BSSGP_ConnHdlr {
1989 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
1990 var Gtp1cUnitdata g_ud_first, g_ud_second;
1991 /* first perform regular attach */
1992 f_TC_attach(id);
1993
1994 /* then activate PDP context on the Gb side */
1995 f_send_l3_gmm_llc(ts_SM_ACT_PDP_REQ(apars.tid, apars.nsapi, apars.sapi, apars.qos, apars.addr,
1996 apars.apn, apars.pco), 0);
1997
1998 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_first {}
1999 log("First createPDPContextRequest received, dropping & waiting for retransmission");
2000 GTP.receive(tr_GTPC_MsgType(?, createPDPContextRequest, ?)) -> value g_ud_second {
2001 if (g_ud_first != g_ud_second) {
2002 setverdict(fail, "Retransmitted GTP message createPDPContextRequest is different from original one!");
2003 mtc.stop;
2004 }
2005 f_process_gtp_ctx_act_req(apars, g_ud_second.gtpc);
2006 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2007 GTP.send(ts_GTPC_CreatePdpResp(g_ud_second.peer, seq_nr,
2008 apars.sgsn_tei_c, apars.gtp_resp_cause,
2009 apars.ggsn_tei_c, apars.ggsn_tei_u,
2010 apars.nsapi,
2011 apars.ggsn_ip_c, apars.ggsn_ip_u, apars.chg_id,
2012 omit, omit));
2013 }
Harald Welte955aa942019-05-03 01:29:29 +02002014 BSSGP[0].receive(tr_SM_ACT_PDP_ACCEPT) {}
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002015
2016 /* Now the same with Deact */
2017 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_REQ_MO(apars.tid, '00'O, false, omit), 0);
2018 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_first {}
2019 log("First deletePDPContextRequest received, dropping & waiting for retransmission");
2020 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextRequest, apars.ggsn_tei_c)) -> value g_ud_second {
2021 if (g_ud_first != g_ud_second) {
2022 setverdict(fail, "Retransmitted GTP message deletePDPContextRequest is different from original one!");
2023 mtc.stop;
2024 }
2025 var integer seq_nr := oct2int(g_ud_second.gtpc.opt_part.sequenceNumber);
2026 BSSGP[0].clear;
2027 GTP.send(ts_GTPC_DeletePdpResp(g_ud_second.peer, seq_nr, apars.sgsn_tei_c, '7F'O));
2028 }
2029 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002030 [] BSSGP[0].receive(tr_SM_DEACT_PDP_ACCEPT_MT(apars.tid)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002031 setverdict(pass);
2032 }
2033 [] as_xid(apars, 0);
2034 }
2035
2036 setverdict(pass);
2037}
2038testcase TC_attach_pdp_act_deact_gtp_retrans() runs on test_CT {
2039 var BSSGP_ConnHdlr vc_conn;
2040 f_init();
2041 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans), testcasename(), g_gb, 27);
2042 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002043 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002044}
2045
2046/* Test that SGSN GTP response retransmit queue works fine */
2047private function f_TC_attach_pdp_act_deact_gtp_retrans_resp(charstring id) runs on BSSGP_ConnHdlr {
2048 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2049 var integer seq_nr := 23;
2050 var Gtp1cUnitdata g_ud_first, g_ud_second;
2051 var template Gtp1cUnitdata g_delete_req;
2052 /* first perform regular attach + PDP context act */
2053 f_TC_attach(id);
2054 f_pdp_ctx_act(apars);
2055
2056 /* Now perform an MT DeleteCtxReq and emulate GGSN didn't receive response and sends a duplicated DeleteCtxReq */
2057 BSSGP[0].clear;
2058 var GtpPeer peer := valueof(ts_GtpPeerC(apars.sgsn_ip_c));
2059 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr, apars.sgsn_tei_c, apars.nsapi, '1'B);
2060 GTP.send(g_delete_req);
2061 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002062 [] BSSGP[0].receive(tr_SM_DEACT_PDP_REQ_MT(apars.tid, ?, true)) {
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002063 f_send_l3_gmm_llc(ts_SM_DEACT_PDP_ACCEPT_MO(apars.tid), 0);
2064 }
2065 [] as_xid(apars, 0);
2066 }
2067 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_first {
2068 if (g_ud_first.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != '80'O) {
2069 setverdict(fail, "Received deletePDPContextResponse cause is not 'Request accepted'");
2070 mtc.stop;
2071 }
2072 };
2073
2074 /* Send duplicate DeleteCtxReq */
2075 log("First deletePDPContextResponse received, dropping & retransmitting retransmission of deletePDPContextRequest");
2076 GTP.send(g_delete_req);
2077 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, apars.ggsn_tei_c)) -> value g_ud_second {
2078 if (g_ud_first != g_ud_second) {
2079 setverdict(fail, "Retransmitted GTP message deletePDPContextResponse is different from original one!");
2080 mtc.stop;
2081 }
2082 }
2083
2084 /* Let's send now a new DeleteCtxReq (increased seq_nr) to make sure it
2085 * is handled differently by SGSN (expect "non-existent" cause) */
2086 g_delete_req := ts_GTPC_DeletePDP(peer, seq_nr + 1, apars.sgsn_tei_c, apars.nsapi, '1'B);
2087 GTP.send(g_delete_req);
2088 /* Response with cause "non-existent" must be sent with TEID 0 according to specs */
2089 GTP.receive(tr_GTPC_MsgType(?, deletePDPContextResponse, '00000000'O)) -> value g_ud_second {
2090 if (g_ud_second.gtpc.gtpc_pdu.deletePDPContextResponse.cause.causevalue != 'C0'O) {
2091 setverdict(fail, "Received deletePDPContextResponse cause is not 'Non-existent'");
2092 mtc.stop;
2093 }
2094 }
2095
2096 setverdict(pass);
2097}
2098testcase TC_attach_pdp_act_deact_gtp_retrans_resp() runs on test_CT {
2099 var BSSGP_ConnHdlr vc_conn;
2100 f_init();
2101 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_deact_gtp_retrans_resp), testcasename(), g_gb, 28);
2102 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002103 f_cleanup();
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02002104}
2105
Alexander Couzens5e307b42018-05-22 18:12:20 +02002106private function f_TC_hlr_location_cancel_request_update(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_UPDATE));
2112 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
Alexander Couzens5e307b42018-05-22 18:12:20 +02002113
2114 /* ensure no Detach Request got received */
2115 timer T := 5.0;
2116 T.start;
2117 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002118 [] BSSGP[0].receive(tr_GMM_DET_REQ_MT(*, *, *)) {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002119 T.stop;
2120 setverdict(fail, "Unexpected GMM Detach Request");
Daniel Willmannafce8662018-07-06 23:11:32 +02002121 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002122 }
2123 [] T.timeout {
2124 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +02002125 mtc.stop;
Alexander Couzens5e307b42018-05-22 18:12:20 +02002126 }
Alexander Couzens0e510e62018-07-28 23:06:00 +02002127 [] BSSGP[0].receive {
Alexander Couzens5e307b42018-05-22 18:12:20 +02002128 repeat;
2129 }
2130 }
2131}
2132
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002133/* ATTACH + PDP CTX ACT + user plane traffic + ERROR IND in MT direction */
2134private function f_TC_attach_pdp_act_user_error_ind_ggsn(charstring id) runs on BSSGP_ConnHdlr {
2135 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2136
2137 /* first perform regular attach */
2138 f_TC_attach(id);
2139 /* then activate PDP context */
2140 f_pdp_ctx_act(apars);
2141 /* then transceive a downlink PDU */
2142 f_gtpu_xceive_mo(apars, f_rnd_octstring(200));
2143
2144 /* Send Error indication as response from upload PDU and expect deact towards MS */
2145 f_pdp_ctx_deact_mt(apars, true);
2146}
2147testcase TC_attach_pdp_act_user_error_ind_ggsn() runs on test_CT {
2148 var BSSGP_ConnHdlr vc_conn;
2149 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002150 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 +02002151 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002152 f_cleanup();
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02002153}
2154
Alexander Couzens5e307b42018-05-22 18:12:20 +02002155testcase TC_hlr_location_cancel_request_update() runs on test_CT {
2156 /* MS <-> SGSN: GMM Attach
2157 * HLR -> SGSN: Cancel Location Request
2158 * HLR <- SGSN: Cancel Location Ack
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_update), testcasename(), g_gb, 31);
Alexander Couzens5e307b42018-05-22 18:12:20 +02002164 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002165 f_cleanup();
Alexander Couzens5e307b42018-05-22 18:12:20 +02002166}
2167
2168
Alexander Couzensc87967a2018-05-22 16:09:54 +02002169private function f_TC_hlr_location_cancel_request_withdraw(charstring id) runs on BSSGP_ConnHdlr {
2170 /* MS: perform regular attach */
2171 f_TC_attach(id);
2172
2173 /* HLR: cancel the location request */
2174 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, OSMO_GSUP_CANCEL_TYPE_WITHDRAW));
2175 GSUP.receive(tr_GSUP_CL_RES(g_pars.imsi));
2176 GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
2177
2178 /* MS: receive a Detach Request */
Harald Welte955aa942019-05-03 01:29:29 +02002179 BSSGP[0].receive(tr_GMM_DET_REQ_MT(c_GMM_DTT_MT_IMSI_DETACH, ?, ?));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002180 f_send_l3(ts_GMM_DET_ACCEPT_MO);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002181
2182 setverdict(pass);
2183}
2184
2185testcase TC_hlr_location_cancel_request_withdraw() runs on test_CT {
2186 /* MS <-> SGSN: GMM Attach
2187 * HLR -> SGSN: Cancel Location Request
2188 * HLR <- SGSN: Cancel Location Ack
2189 * MS <- SGSN: Detach Request
2190 * SGSN-> MS: Detach Complete
2191 */
2192 var BSSGP_ConnHdlr vc_conn;
2193 f_init();
2194 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002195 vc_conn := f_start_handler(refers(f_TC_hlr_location_cancel_request_withdraw), testcasename(), g_gb, 29);
Alexander Couzensc87967a2018-05-22 16:09:54 +02002196 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002197 f_cleanup();
Alexander Couzensc87967a2018-05-22 16:09:54 +02002198}
2199
2200
Alexander Couzens6c47f292018-05-22 17:09:49 +02002201private function f_hlr_location_cancel_request_unknown_subscriber(
2202 charstring id,
2203 GSUP_CancelType canceltype) runs on BSSGP_ConnHdlr {
2204
2205 /* HLR: cancel the location request */
2206 GSUP.send(ts_GSUP_CL_REQ(g_pars.imsi, canceltype));
2207
2208 /* cause 2 = IMSI_UNKNOWN */
2209 GSUP.receive(tr_GSUP_CL_ERR(g_pars.imsi, 2));
2210
2211 setverdict(pass);
2212}
2213
2214private function f_TC_hlr_location_cancel_request_unknown_subscriber_withdraw(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002215 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002216}
2217
2218testcase TC_hlr_location_cancel_request_unknown_subscriber_withdraw() runs on test_CT {
2219 /* HLR -> SGSN: Cancel Location Request
2220 * HLR <- SGSN: Cancel Location Error
2221 */
2222
2223 var BSSGP_ConnHdlr vc_conn;
2224 f_init();
2225 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002226 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 +02002227 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002228 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002229}
2230
2231private function f_TC_hlr_location_cancel_request_unknown_subscriber_update(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensace6fc62018-06-05 16:29:02 +02002232 f_hlr_location_cancel_request_unknown_subscriber(id, OSMO_GSUP_CANCEL_TYPE_WITHDRAW);
Alexander Couzens6c47f292018-05-22 17:09:49 +02002233}
2234
2235testcase TC_hlr_location_cancel_request_unknown_subscriber_update() runs on test_CT {
2236 /* HLR -> SGSN: Cancel Location Request
2237 * HLR <- SGSN: Cancel Location Error
2238 */
2239
2240 var BSSGP_ConnHdlr vc_conn;
2241 f_init();
2242 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002243 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 +02002244 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002245 f_cleanup();
Alexander Couzens6c47f292018-05-22 17:09:49 +02002246}
2247
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002248private function f_TC_attach_detach_check_subscriber_list(charstring id) runs on BSSGP_ConnHdlr {
2249 f_TC_attach(id);
2250 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2251}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002252
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002253testcase TC_attach_detach_check_subscriber_list() runs on test_CT {
2254 /* MS <-> SGSN: Attach
2255 * MS -> SGSN: Detach Req (Power off)
2256 * VTY -> SGSN: Check if MS is NOT in subscriber cache
2257 */
2258 var BSSGP_ConnHdlr vc_conn;
2259 var integer id := 33;
2260 var charstring imsi := hex2str(f_gen_imsi(id));
2261
2262 f_init();
Alexander Couzens51114d12018-07-31 18:41:56 +02002263 vc_conn := f_start_handler(refers(f_TC_attach_detach_check_subscriber_list), testcasename(), g_gb, id);
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002264 vc_conn.done;
2265
2266 f_vty_transceive_not_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002267 f_cleanup();
Alexander Couzens49bb4b42018-06-05 16:28:36 +02002268}
Alexander Couzens6c47f292018-05-22 17:09:49 +02002269
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002270/* Attempt an attach, but loose the Identification Request (IMEI) */
2271private function f_TC_attach_no_imei_response(charstring id) runs on BSSGP_ConnHdlr {
2272 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002273 var MobileIdentityLV mi;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002274
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002275 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 +02002276
2277 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002278 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002279 /* break */
2280 }
Harald Welte955aa942019-05-03 01:29:29 +02002281 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002282 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002283 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002284 repeat;
2285 }
Harald Welte955aa942019-05-03 01:29:29 +02002286 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002287 /* ignore ID REQ IMEI */
2288 count_req := count_req + 1;
2289 repeat;
2290 }
2291 }
2292 if (count_req != 5) {
2293 setverdict(fail, "Did not received GMM ID Request Type IMEI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002294 mtc.stop;
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002295 }
2296 setverdict(pass);
2297}
2298
2299testcase TC_attach_no_imei_response() runs on test_CT {
2300 /* MS -> SGSN: Attach Request IMSI
2301 * MS <- SGSN: Identity Request IMSI (optional)
2302 * MS -> SGSN: Identity Response IMSI (optional)
2303 * MS <- SGSN: Identity Request IMEI
2304 * MS -x SGSN: no response
2305 * MS <- SGSN: re-send: Identity Request IMEI 4x
2306 * MS <- SGSN: Attach Reject
2307 */
2308 var BSSGP_ConnHdlr vc_conn;
2309 f_init();
2310 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002311 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 +02002312 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002313 f_cleanup();
Alexander Couzens667dd7f2018-06-12 16:24:01 +02002314}
2315
Alexander Couzens53f20562018-06-12 16:24:12 +02002316/* Attempt an attach, but loose the Identification Request (IMSI) */
2317private function f_TC_attach_no_imsi_response(charstring id) runs on BSSGP_ConnHdlr {
2318 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002319 var MobileIdentityLV mi;
Alexander Couzens53f20562018-06-12 16:24:12 +02002320
2321 /* set p_tmsi to use it in Attach Req via f_mi_get_lv() */
2322 g_pars.p_tmsi := 'c0000035'O;
2323
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002324 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 +02002325
2326 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002327 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002328 /* break */
2329 }
Harald Welte955aa942019-05-03 01:29:29 +02002330 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002331 /* ignore ID REQ IMSI */
2332 count_req := count_req + 1;
2333 repeat;
2334 }
Harald Welte955aa942019-05-03 01:29:29 +02002335 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzens53f20562018-06-12 16:24:12 +02002336 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002337 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzens53f20562018-06-12 16:24:12 +02002338 repeat;
2339 }
2340 }
2341 if (count_req != 5) {
2342 setverdict(fail, "Did not received GMM ID Request Type IMSI 5 times!");
Daniel Willmannafce8662018-07-06 23:11:32 +02002343 mtc.stop;
Alexander Couzens53f20562018-06-12 16:24:12 +02002344 }
2345 setverdict(pass);
2346}
2347
2348testcase TC_attach_no_imsi_response() runs on test_CT {
2349 /* MS -> SGSN: Attach Request TMSI (unknown)
2350 * MS <- SGSN: Identity Request IMEI (optional)
2351 * MS -> SGSN: Identity Response IMEI (optional)
2352 * MS <- SGSN: Identity Request IMSI
2353 * MS -x SGSN: no response
2354 * MS <- SGSN: re-send: Identity Request IMSI 4x
2355 * MS <- SGSN: Attach Reject
2356 */
2357 var BSSGP_ConnHdlr vc_conn;
2358 f_init();
2359 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002360 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 +02002361 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002362 f_cleanup();
Alexander Couzens53f20562018-06-12 16:24:12 +02002363}
2364
Alexander Couzenscf818962018-06-05 18:00:00 +02002365private function f_sgsn_vty_destroy_subscriber_imsi(TELNETasp_PT pt, charstring imsi) {
2366 f_vty_transceive(pt, "update-subscriber imsi " & imsi & " destroy");
2367}
2368
2369testcase TC_attach_check_subscriber_list() runs on test_CT {
2370 /* MS <-> SGSN: Attach
2371 * VTY -> SGSN: Check if MS is in subscriber cache
2372 */
2373 var BSSGP_ConnHdlr vc_conn;
2374 var integer id := 34;
2375 var charstring imsi := hex2str(f_gen_imsi(id));
2376
2377 f_init();
2378 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002379 vc_conn := f_start_handler(refers(f_TC_attach), testcasename(), g_gb, id);
Alexander Couzenscf818962018-06-05 18:00:00 +02002380 vc_conn.done;
2381
2382 f_vty_transceive_match(SGSNVTY, "show subscriber cache", pattern "* IMSI: {imsi}*");
2383 f_sgsn_vty_destroy_subscriber_imsi(SGSNVTY, imsi);
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002384 f_cleanup();
Alexander Couzenscf818962018-06-05 18:00:00 +02002385}
2386
Alexander Couzensf9858652018-06-07 16:14:53 +02002387private function f_TC_attach_closed_imsi_added(charstring id) runs on BSSGP_ConnHdlr {
2388 var RoutingAreaIdentificationV old_ra := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002389 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzensf9858652018-06-07 16:14:53 +02002390
2391 /* unregister the old IMSI */
2392 f_bssgp_client_unregister(g_pars.imsi);
2393 /* Simulate a foreign IMSI */
Alexander Couzens03d12242018-08-07 16:13:52 +02002394 g_pars.imsi := '001010123456700'H;
Harald Welte5339b2e2020-10-04 22:52:56 +02002395 f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
Alexander Couzensf9858652018-06-07 16:14:53 +02002396
2397 /* there is no auth */
2398 g_pars.net.expect_auth := false;
2399
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002400 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit));
Alexander Couzensf9858652018-06-07 16:14:53 +02002401 f_gmm_auth();
2402 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002403 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzensf9858652018-06-07 16:14:53 +02002404 setverdict(fail, "Received unexpected GMM Attach REJECT");
Daniel Willmannafce8662018-07-06 23:11:32 +02002405 mtc.stop;
Alexander Couzensf9858652018-06-07 16:14:53 +02002406 }
Harald Welte955aa942019-05-03 01:29:29 +02002407 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) -> value l3_mt {
2408 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002409 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzensf9858652018-06-07 16:14:53 +02002410 setverdict(pass);
2411 }
2412 }
2413}
Alexander Couzens03d12242018-08-07 16:13:52 +02002414
2415private function f_TC_attach_closed_add_vty(charstring id) runs on BSSGP_ConnHdlr {
2416
2417 f_TC_attach_closed_foreign(id);
2418 f_TC_attach_closed_imsi_added(id);
2419
2420}
2421
2422
Alexander Couzensf9858652018-06-07 16:14:53 +02002423testcase TC_attach_closed_add_vty() runs on test_CT {
2424 /* VTY-> SGSN: policy close
2425 * MS -> SGSN: Attach Request
2426 * MS <- SGSN: Identity Request IMSI
2427 * MS -> SGSN: Identity Response IMSI
2428 * MS <- SGSN: Attach Reject
2429 * VTY-> SGSN: policy imsi-acl add IMSI
2430 * MS -> SGSN: Attach Request
2431 * MS <- SGSN: Identity Request IMSI
2432 * MS -> SGSN: Identity Response IMSI
2433 * MS <- SGSN: Identity Request IMEI
2434 * MS -> SGSN: Identity Response IMEI
2435 * MS <- SGSN: Attach Accept
2436 */
2437 var BSSGP_ConnHdlr vc_conn;
2438 f_init();
2439 f_sleep(1.0);
2440 f_vty_config(SGSNVTY, "sgsn", "auth-policy closed");
2441 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456789");
Alexander Couzens03d12242018-08-07 16:13:52 +02002442 f_vty_config(SGSNVTY, "sgsn", "imsi-acl del 001010123456700");
2443 f_vty_config(SGSNVTY, "sgsn", "imsi-acl add 001010123456700");
Alexander Couzensf9858652018-06-07 16:14:53 +02002444 /* test with foreign IMSI: Must Reject */
Alexander Couzens03d12242018-08-07 16:13:52 +02002445 vc_conn := f_start_handler(refers(f_TC_attach_closed_add_vty), testcasename(), g_gb, 9);
Alexander Couzensf9858652018-06-07 16:14:53 +02002446 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002447 f_cleanup();
Alexander Couzensf9858652018-06-07 16:14:53 +02002448}
2449
Alexander Couzens0085bd72018-06-12 19:08:44 +02002450/* Attempt an attach, but never answer a Attach Complete */
2451private function f_TC_attach_check_complete_resend(charstring id) runs on BSSGP_ConnHdlr {
2452 var integer count_req := 0;
2453
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002454 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 +02002455 f_gmm_auth();
Pau Espin Pedrol4b290a22019-09-10 19:49:41 +02002456 /* Expect SGSN to perform LU with HLR */
2457 f_gmm_gsup_lu_isd();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002458
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002459 timer T := 10.0;
2460 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002461 alt {
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002462 [] T.timeout {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002463 /* break */
2464 }
Harald Welte955aa942019-05-03 01:29:29 +02002465 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT(*, *, *)) {
Alexander Couzens0085bd72018-06-12 19:08:44 +02002466 /* ignore */
2467 count_req := count_req + 1;
Alexander Couzensfa0a75f2018-08-07 15:45:04 +02002468 T.start;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002469 repeat;
2470 }
2471 }
2472 if (count_req != 5) {
2473 setverdict(fail, "Did not received GMM Attach Complete.");
Daniel Willmannafce8662018-07-06 23:11:32 +02002474 mtc.stop;
Alexander Couzens0085bd72018-06-12 19:08:44 +02002475 }
2476 setverdict(pass);
2477}
2478
2479testcase TC_attach_check_complete_resend() runs on test_CT {
2480 /* MS -> SGSN: Attach Request IMSI
2481 * MS <- SGSN: Identity Request *
2482 * MS -> SGSN: Identity Response *
2483 * MS <- SGSN: Attach Complete 5x
2484 */
2485 var BSSGP_ConnHdlr vc_conn;
2486 f_init();
2487 f_sleep(1.0);
Alexander Couzens51114d12018-07-31 18:41:56 +02002488 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 +02002489 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002490 f_cleanup();
Alexander Couzens0085bd72018-06-12 19:08:44 +02002491}
2492
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002493friend function f_routing_area_update(RoutingAreaIdentificationV ra, integer ran_index := 0) runs on BSSGP_ConnHdlr {
Harald Welte955aa942019-05-03 01:29:29 +02002494 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002495 var PDU_DTAP_PS_MT mt;
2496 var template OCT4 p_tmsi := omit;
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002497
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002498 if (is_iu(ran_index)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002499 p_tmsi := g_pars.p_tmsi;
2500 }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002501 /* then send RAU */
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002502 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 +02002503 alt {
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002504 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_ACCEPT) -> value l3_mt {
2505 f_process_rau_accept(l3_mt.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2506 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002507 setverdict(pass);
2508 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002509 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_ACCEPT)) -> value mt {
2510 f_process_rau_accept(mt.dtap.msgs.gprs_mm.routingAreaUpdateAccept, ran_index);
2511 f_send_l3(ts_GMM_RAU_COMPL, ran_index);
Alexander Couzens5d56f522019-09-03 12:36:18 +02002512 setverdict(pass);
2513 }
2514
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002515 [is_gb(ran_index)] BSSGP[ran_index].receive(tr_GMM_RAU_REJECT) {
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002516 setverdict(fail, "Unexpected RAU Reject");
2517 mtc.stop;
2518 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002519 [is_iu(ran_index)] BSSAP.receive(tr_PDU_DTAP_PS_MT(tr_GMM_RAU_REJECT)) {
Alexander Couzens5d56f522019-09-03 12:36:18 +02002520 setverdict(fail, "Unexpected RAU Reject");
2521 mtc.stop;
2522 }
2523
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002524 [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 +02002525 key_sts := ?)) {
2526 var IntegrityProtectionAlgorithm uia_chosen := 0; /* 0 = standard_UMTS_integrity_algorithm_UIA1 */
2527 BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
Alexander Couzensed61ae82019-09-15 23:18:08 +02002528 BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)))
Daniel Willmann1c116112020-01-22 17:48:31 +01002529 repeat;
Alexander Couzens5d56f522019-09-03 12:36:18 +02002530 }
Alexander Couzensbe76d9c2019-09-15 22:48:03 +02002531 [is_gb(ran_index)] BSSGP[ran_index].receive { repeat; }
2532 [is_iu(ran_index)] BSSAP.receive { repeat; }
Alexander Couzens5dce90d2018-07-31 03:16:37 +02002533 }
2534}
2535
Alexander Couzensbfda9212018-07-31 03:17:33 +02002536private function f_TC_attach_rau_a_a(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbfda9212018-07-31 03:17:33 +02002537 /* first perform regular attach */
2538 f_TC_attach(id);
2539
2540 /* then send RAU */
2541 f_routing_area_update(g_pars.ra);
2542
2543 /* do another RAU */
2544 f_routing_area_update(g_pars.ra);
2545
2546 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2547}
2548
2549testcase TC_attach_rau_a_a() runs on test_CT {
2550 /* MS <-> SGSN: Successful Attach
2551 * MS -> SGSN: Routing Area Update Request
2552 * MS <- SGSN: Routing Area Update Accept
2553 * MS -> SGSN: Routing Area Update Request
2554 * MS <- SGSN: Routing Area Update Accept
2555 * MS -> SGSN: Detach (PowerOff)
2556 */
2557 var BSSGP_ConnHdlr vc_conn;
2558 f_init();
2559 f_sleep(1.0);
2560 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_a), testcasename(), g_gb, 37);
2561 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002562 f_cleanup();
Alexander Couzensbfda9212018-07-31 03:17:33 +02002563}
2564
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002565private function f_TC_attach_rau_a_b(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002566 f_TC_attach(id);
2567
2568 log("attach complete sending rau");
2569 f_routing_area_update(g_pars.ra, 0);
2570
2571 log("rau complete unregistering");
2572 f_bssgp_client_unregister(g_pars.imsi);
Harald Welte5339b2e2020-10-04 22:52:56 +02002573 f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002574
2575 log("sending second RAU via different RA");
2576 f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);
2577
2578 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true, 1);
2579}
2580
2581testcase TC_attach_rau_a_b() runs on test_CT {
2582 /* MS <-> SGSN: Successful Attach
2583 * MS -> SGSN: Routing Area _a_ Update Request
2584 * MS <- SGSN: Routing Area _a_ Update Accept
2585 * MS -> SGSN: Routing Area _b_ Update Request
2586 * MS <- SGSN: Routing Area _b_ Update Accept
2587 * MS -> SGSN: Detach (PowerOff)
2588 */
2589 var BSSGP_ConnHdlr vc_conn;
2590 f_init();
2591 f_sleep(1.0);
2592 vc_conn := f_start_handler(refers(f_TC_attach_rau_a_b), testcasename(), g_gb, 38);
2593 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002594 f_cleanup();
Alexander Couzensbe837bd2018-07-31 04:20:11 +02002595}
2596
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002597private function f_TC_attach_gmm_attach_req_while_gmm_attach(charstring id) runs on BSSGP_ConnHdlr {
2598 var integer count_req := 0;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07002599 var MobileIdentityLV mi;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002600 var RoutingAreaIdentificationV rand_rai := f_random_RAI();
Harald Welte955aa942019-05-03 01:29:29 +02002601 var PDU_L3_SGSN_MS l3_mt;
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002602
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002603 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002604
2605 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002606 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002607 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2608 mtc.stop;
2609 }
Harald Welte955aa942019-05-03 01:29:29 +02002610 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002611 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002612 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002613 repeat;
2614 }
Harald Welte955aa942019-05-03 01:29:29 +02002615 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002616 /* send out a second GMM_Attach Request.
2617 * If the SGSN follows the rules, this 2nd ATTACH REQ should be ignored, because
2618 * of the same content */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002619 f_send_l3(ts_GMM_ATTACH_REQ(f_mi_get_lv(), rand_rai, true, false, omit, omit));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002620 mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002621 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002622 }
2623 }
2624 f_sleep(1.0);
2625
2626 /* we've sent already a IMEI answer, we should NOT asked again for IMEI */
2627 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002628 [] BSSGP[0].receive(tr_GMM_ID_REQ('001'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002629 mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002630 f_send_l3(ts_GMM_ID_RESP(mi));
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002631 repeat;
2632 }
Harald Welte955aa942019-05-03 01:29:29 +02002633 [] BSSGP[0].receive(tr_GMM_ID_REQ('010'B)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002634 setverdict(fail, "Unexpected GMM ID REQ (IMEI).");
2635 mtc.stop;
2636 }
Harald Welte955aa942019-05-03 01:29:29 +02002637 [] BSSGP[0].receive(tr_GMM_ATTACH_REJECT(?)) {
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002638 setverdict(fail, "Unexpected GMM ATTACH REJECT");
2639 mtc.stop;
2640 }
Harald Welte955aa942019-05-03 01:29:29 +02002641 [] BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2642 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002643 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002644 setverdict(pass);
2645 /* FIXME: Extract P-TMSI, if any. Only send Complete if necessary */
2646 }
2647 }
2648}
2649
2650testcase TC_attach_gmm_attach_req_while_gmm_attach() runs on test_CT {
2651 /* Testing if the SGSN ignore Attach Request with the exact same content */
2652 /* MS -> SGSN: Attach Request IMSI
2653 * MS <- SGSN: Identity Request IMSI (optional)
2654 * MS -> SGSN: Identity Response IMSI (optional)
2655 * MS <- SGSN: Identity Request IMEI
2656 * MS -> SGSN: Attach Request (2nd)
2657 * MS <- SGSN: Identity Response IMEI
2658 * MS <- SGSN: Attach Accept
2659 * MS -> SGSN: Attach Complete
2660 */
2661 var BSSGP_ConnHdlr vc_conn;
2662 f_init();
2663 f_sleep(1.0);
2664 f_vty_config(SGSNVTY, "sgsn", "auth-policy accept-all");
2665 vc_conn := f_start_handler(refers(f_TC_attach_gmm_attach_req_while_gmm_attach), testcasename(), g_gb, 39);
2666 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002667 f_cleanup();
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02002668}
2669
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002670private function f_TC_attach_usim_resync(charstring id) runs on BSSGP_ConnHdlr {
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002671 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2672
2673 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2674
2675 /* send Attach Request */
2676 /* indicate R99 capability of the MS to enable UMTS AKA in presence of
2677 * 3G auth vectors */
2678 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.revisionLevelIndicatior := '1'B;
2679 /* The thing is, if the solSACapability is 'omit', then the
2680 * revisionLevelIndicatior is at the wrong place! */
2681 attach_req.msgs.gprs_mm.attachRequest.msNetworkCapability.msNetworkCapabilityV.solSACapability := '0'B;
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002682 f_send_l3(attach_req);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002683
2684 /* do the auth */
2685 var PDU_L3_MS_SGSN l3_mo;
2686 var PDU_L3_SGSN_MS l3_mt;
2687 var default di := activate(as_mm_identity());
2688
2689 var GSUP_IE auth_tuple;
2690 var template AuthenticationParameterAUTNTLV autn;
2691
2692 g_pars.vec := f_gen_auth_vec_3g();
2693 autn := {
2694 elementIdentifier := '28'O,
2695 lengthIndicator := lengthof(g_pars.vec.autn),
2696 autnValue := g_pars.vec.autn
2697 };
2698 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2699 g_pars.vec.sres,
2700 g_pars.vec.kc,
2701 g_pars.vec.ik,
2702 g_pars.vec.ck,
2703 g_pars.vec.autn,
2704 g_pars.vec.res));
2705 log("GSUP sends 2G and 3G auth tuples", auth_tuple);
2706 GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
2707 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2708
2709 var template PDU_L3_SGSN_MS auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2710 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002711 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002712
2713 /* send the gmm auth failure with resync IE */
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002714 f_send_l3(ts_GMM_AUTH_FAIL_UMTS_AKA_RESYNC(g_pars.vec.auts));
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002715
2716 /* wait for the GSUP resync request */
2717 GSUP.receive(tr_GSUP_SAI_REQ_UMTS_AKA_RESYNC(
2718 g_pars.imsi,
2719 g_pars.vec.auts,
2720 g_pars.vec.rand));
2721
2722 /* generate new key material */
2723 g_pars.vec := f_gen_auth_vec_3g();
2724 autn := {
2725 elementIdentifier := '28'O,
2726 lengthIndicator := lengthof(g_pars.vec.autn),
2727 autnValue := g_pars.vec.autn
2728 };
2729
2730 auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
2731 g_pars.vec.sres,
2732 g_pars.vec.kc,
2733 g_pars.vec.ik,
2734 g_pars.vec.ck,
2735 g_pars.vec.autn,
2736 g_pars.vec.res));
2737 /* send new key material */
2738 GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
2739
2740 /* wait for the new Auth Request */
2741 auth_ciph_req := tr_GMM_AUTH_REQ(g_pars.vec.rand);
2742 auth_ciph_req.msgs.gprs_mm.authenticationAndCipheringRequest.authenticationParameterAUTN := autn;
Harald Welte955aa942019-05-03 01:29:29 +02002743 BSSGP[0].receive(auth_ciph_req) -> value l3_mt;
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002744 var BIT4 ac_ref := l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.acReferenceNumber.valueField;
2745 var template PDU_L3_MS_SGSN auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2746 auth_ciph_resp := ts_GMM_AUTH_RESP_2G(ac_ref, g_pars.vec.sres);
2747 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationParResp := {
2748 valueField := substr(g_pars.vec.res, 0, 4)
2749 };
2750 auth_ciph_resp.msgs.gprs_mm.authenticationAndCipheringResponse.authenticationRespParExt := {
2751 elementIdentifier := '21'O,
2752 lengthIndicator := lengthof(g_pars.vec.res) - 4,
2753 valueField := substr(g_pars.vec.res, 4, lengthof(g_pars.vec.res) - 4)
2754 };
2755 l3_mo := valueof(auth_ciph_resp);
2756 if (ispresent(l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest) and
2757 l3_mt.msgs.gprs_mm.authenticationAndCipheringRequest.imeisvRequest.valueField == '001'B) {
2758 l3_mo.msgs.gprs_mm.authenticationAndCipheringResponse.imeisv :=
2759 valueof(ts_MI_IMEISV_TLV(g_pars.imei & '0'H));
2760 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002761 f_send_l3(l3_mo);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002762 deactivate(di);
2763
2764 /* Expect SGSN to perform LU with HLR */
2765 f_gmm_gsup_lu_isd();
2766
Harald Welte955aa942019-05-03 01:29:29 +02002767 BSSGP[0].receive(tr_GMM_ATTACH_ACCEPT('001'B, ?, ?)) -> value l3_mt {
2768 f_process_attach_accept(l3_mt.msgs.gprs_mm.attachAccept);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002769 }
Alexander Couzens4444b5a2019-08-13 13:25:32 +02002770 f_send_l3(ts_GMM_ATTACH_COMPL);
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002771 setverdict(pass);
2772}
2773
2774testcase TC_attach_usim_resync() runs on test_CT {
2775 /* MS -> SGSN: Attach Request
2776 * MS <- SGSN: Identity Request IMSI
2777 * MS -> SGSN: Identity Response IMSI
2778 * MS <- SGSN: Identity Request IMEI
2779 * MS -> SGSN: Identity Response IMEI
2780 * HLR<- SGSN: SAI Request
2781 * HLR-> SGSN: SAI Response
2782 * MS <- SGSN: Auth Request
2783 * MS -> SGSN: Auth Failure (with AUTS)
2784 * HLR<- SGSN: SAI Request (with AUTS & RAND)
2785 * HLR-> SGSN: SAI Response (new key material)
2786 * MS <- SGSN: Auth Request (new key material)
2787 * MS -> SGSN: Auth Response
2788 * MS <- SGSN: Attach Accept
2789 * MS -> SGSN: Attach Complete
2790 */
2791 var BSSGP_ConnHdlr vc_conn;
2792 f_init();
2793 f_sleep(1.0);
2794 vc_conn := f_start_handler(refers(f_TC_attach_usim_resync), testcasename(), g_gb, 40);
2795 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002796 f_cleanup();
Alexander Couzens0c6324f2018-09-14 16:37:04 +02002797}
2798
Harald Weltea05b8072019-04-23 22:35:05 +02002799
2800/* Send LLC NULL to see if the SGSN survives it (OS#3952) */
2801private function f_TC_llc_null(charstring id) runs on BSSGP_ConnHdlr {
2802 f_gmm_attach(false, false);
2803 f_sleep(1.0);
2804 f_send_llc(ts_LLC_NULL('0'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
2805 /* try to detach to check if SGSN is still alive */
2806 f_detach_mo(c_GMM_DTT_MO_GPRS, true, true);
2807}
2808testcase TC_llc_null() runs on test_CT {
2809 var BSSGP_ConnHdlr vc_conn;
2810 f_init();
2811 f_sleep(1.0);
2812 vc_conn := f_start_handler(refers(f_TC_llc_null), testcasename(), g_gb, 41);
2813 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002814 f_cleanup();
Harald Weltea05b8072019-04-23 22:35:05 +02002815}
2816
Harald Welte645a1512019-04-23 23:18:23 +02002817/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2818private function f_TC_llc_sabm_dm_llgmm(charstring id) runs on BSSGP_ConnHdlr {
2819 f_gmm_attach(false, false);
2820 f_sleep(1.0);
2821 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LLGMM, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002822 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LLGMM, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002823 setverdict(pass);
2824}
2825testcase TC_llc_sabm_dm_llgmm() runs on test_CT {
2826 var BSSGP_ConnHdlr vc_conn;
2827 f_init();
2828 f_sleep(1.0);
2829 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_llgmm), testcasename(), g_gb, 42);
2830 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002831 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002832}
2833
2834/* Send LLC SABM to see if the SGSN rejects it properly with DM */
2835private function f_TC_llc_sabm_dm_ll5(charstring id) runs on BSSGP_ConnHdlr {
2836 f_gmm_attach(false, false);
2837 f_sleep(1.0);
2838 f_send_llc(ts_LLC_SABM({}, '1'B, c_LLC_SAPI_LL5, LLC_CR_UL_CMD));
Harald Welte955aa942019-05-03 01:29:29 +02002839 BSSGP[0].receive(tr_LLC_DM(?, c_LLC_SAPI_LL5, LLC_CR_DL_RSP));
Harald Welte645a1512019-04-23 23:18:23 +02002840 setverdict(pass);
2841}
2842testcase TC_llc_sabm_dm_ll5() runs on test_CT {
2843 var BSSGP_ConnHdlr vc_conn;
2844 f_init();
2845 f_sleep(1.0);
2846 vc_conn := f_start_handler(refers(f_TC_llc_sabm_dm_ll5), testcasename(), g_gb, 43);
2847 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002848 f_cleanup();
Harald Welte645a1512019-04-23 23:18:23 +02002849}
2850
Harald Welte2aaac1b2019-05-02 10:02:53 +02002851/* test XID handshake with empty L3 info: expect empty return (some phones require that, OS#3426 */
2852private function f_TC_xid_empty_l3(charstring id) runs on BSSGP_ConnHdlr {
2853 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2854 var template (value) XID_Information xid;
2855 var template XID_Information xid_rx;
2856
2857 /* first perform regular attach */
2858 f_TC_attach(id);
2859 /* then activate PDP context */
2860 f_pdp_ctx_act(apars);
2861
2862 /* start MO XID */
2863 xid := { ts_XID_L3(''O) };
2864 xid_rx := { tr_XID_L3(''O) };
2865 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2866 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002867 [] BSSGP[0].receive(tr_LLC_XID(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002868 [] as_xid(apars);
2869 }
2870 setverdict(pass);
2871}
2872testcase TC_xid_empty_l3() runs on test_CT {
2873 var BSSGP_ConnHdlr vc_conn;
2874 f_init();
2875 f_sleep(1.0);
2876 vc_conn := f_start_handler(refers(f_TC_xid_empty_l3), testcasename(), g_gb, 44);
2877 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002878 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002879}
2880
2881private function f_TC_xid_n201u(charstring id) runs on BSSGP_ConnHdlr {
2882 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2883 var template (value) XID_Information xid;
2884 var template XID_Information xid_rx;
2885
2886 /* first perform regular attach */
2887 f_TC_attach(id);
2888 /* then activate PDP context */
2889 f_pdp_ctx_act(apars);
2890
2891 /* start MO XID */
2892 xid := { ts_XID_N201U(1234) };
2893 xid_rx := { tr_XID_N201U(1234) };
2894 f_send_llc(ts_LLC_XID_MO_CMD(xid, apars.sapi));
2895 alt {
Harald Welte955aa942019-05-03 01:29:29 +02002896 [] BSSGP[0].receive(tr_LLC_XID_MT_RSP(xid_rx, apars.sapi));
Harald Welte2aaac1b2019-05-02 10:02:53 +02002897 [] as_xid(apars);
2898 }
2899 setverdict(pass);
2900}
2901testcase TC_xid_n201u() runs on test_CT {
2902 var BSSGP_ConnHdlr vc_conn;
2903 f_init();
2904 f_sleep(1.0);
2905 vc_conn := f_start_handler(refers(f_TC_xid_n201u), testcasename(), g_gb, 45);
2906 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002907 f_cleanup();
Harald Welte2aaac1b2019-05-02 10:02:53 +02002908}
2909
Alexander Couzens6bee0872019-05-11 01:48:50 +02002910private function f_TC_attach_pdp_act_gmm_detach(charstring id) runs on BSSGP_ConnHdlr {
2911 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2912
2913 /* first perform regular attach */
2914 f_TC_attach(id);
2915 /* then activate PDP context */
2916 f_pdp_ctx_act(apars);
2917 /* do a normal detach */
2918 f_detach_mo(c_GMM_DTT_MO_GPRS, false, true);
2919}
2920
2921testcase TC_attach_pdp_act_gmm_detach() runs on test_CT {
2922 /* MS -> SGSN: Attach Request
2923 * MS <-> SGSN: [..]
2924 * MS -> SGSN: Attach Complete
2925 * MS -> SGSN: PDP Activate Request
2926 * MS <- SGSN: PDP Activate Accept
2927 * MS -> SGSN: GMM Detach Request
2928 * MS <- SGSN: GMM Detach Accept
2929 */
2930 var BSSGP_ConnHdlr vc_conn;
2931 f_init();
2932 vc_conn := f_start_handler(refers(f_TC_attach_pdp_act_gmm_detach), testcasename(), g_gb, 26);
2933 vc_conn.done;
Pau Espin Pedrolce0d6152019-08-27 19:07:27 +02002934 f_cleanup();
Alexander Couzens6bee0872019-05-11 01:48:50 +02002935}
Harald Welte645a1512019-04-23 23:18:23 +02002936
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01002937private function f_TC_attach_req_id_req_ra_update(charstring id) runs on BSSGP_ConnHdlr {
2938 var RoutingAreaIdentificationV old_ra := f_random_RAI();
2939 var RoutingAreaIdentificationV new_ra := f_random_RAI();
2940 while (old_ra == new_ra) { new_ra := f_random_RAI(); };
2941 var template PDU_L3_MS_SGSN attach_req := ts_GMM_ATTACH_REQ(f_mi_get_lv(), old_ra, false, false, omit, omit);
2942 var PDU_L3_SGSN_MS l3_mt;
2943
2944 f_send_l3(attach_req, 0);
2945
2946 BSSGP[0].receive(tr_GMM_ID_REQ(?));
2947
2948 f_send_l3(ts_GMM_RAU_REQ(f_mi_get_lv(), GPRS_UPD_T_RA, new_ra, false, omit, omit));
2949 alt {
2950 [] BSSGP[0].receive(tr_GMM_RAU_REJECT('0a'O)) {
2951 setverdict(pass);
2952 }
2953 [] BSSGP[0].receive { repeat; }
2954 }
2955}
2956
2957/* This test triggers crash in osmo-sgsn before osmo-sgsn.git I64fa5cf1b427d3abb99e553e584897261a827ce6.
2958 * See OS#3957 and OS#4245 for more information.
2959 */
2960testcase TC_attach_req_id_req_ra_update() runs on test_CT {
2961 /*
2962 * MS --> SGSN: Attach Req (TMSI, RAI=901-70-356-101)
2963 * MS <-- SGSN: Identity Request (IMEI)
2964 * MS --> SGSN: RA Updating (RAI=901-70-2758-208)
2965 */
2966 var BSSGP_ConnHdlr vc_conn;
2967 f_init();
2968 vc_conn := f_start_handler(refers(f_TC_attach_req_id_req_ra_update), testcasename(), g_gb, 47);
2969 vc_conn.done;
2970 f_cleanup();
2971}
2972
Harald Welte8e5932e2020-06-17 22:12:54 +02002973private altstep as_nopaging_ps(integer ran_idx := 0) runs on BSSGP_ConnHdlr {
2974var PDU_BSSGP rx;
2975[] BSSGP_SIG[ran_idx].receive(tr_BSSGP_PS_PAGING(?)) -> value rx {
2976 setverdict(fail, "Received unexpected PS PAGING: ", rx);
2977 mtc.stop;
2978 }
2979}
2980
2981/* SUSPEND, then DL traffic: should not pass + no paging expected */
2982private function f_TC_suspend_nopaging(charstring id) runs on BSSGP_ConnHdlr {
2983 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
2984 var default d;
2985
2986 /* first perform regular attach */
2987 f_TC_attach(id);
2988 /* then activate PDP context */
2989 f_pdp_ctx_act(apars);
2990 /* then transceive a downlink PDU */
2991 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
2992
2993 /* now suspend GPRS */
2994 f_bssgp_suspend();
2995
2996 d := activate(as_nopaging_ps());
2997
2998 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
2999 * nor any related paging requests */
3000 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3001
3002 deactivate(d);
3003}
3004testcase TC_suspend_nopaging() runs on test_CT {
3005 var BSSGP_ConnHdlr vc_conn;
3006 f_init();
3007 f_sleep(1.0);
3008 vc_conn := f_start_handler(refers(f_TC_suspend_nopaging), testcasename(), g_gb, 48);
3009 vc_conn.done;
3010 f_cleanup();
3011}
3012
3013
3014/* SUSPEND, then RESUME: data expected to flow after explicit resume */
3015private function f_TC_suspend_resume(charstring id) runs on BSSGP_ConnHdlr {
3016 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3017 var OCT1 susp_ref;
3018 var default d;
3019
3020 /* first perform regular attach */
3021 f_TC_attach(id);
3022 /* then activate PDP context */
3023 f_pdp_ctx_act(apars);
3024 /* then transceive a downlink PDU */
3025 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3026
3027 /* now suspend GPRS */
3028 susp_ref := f_bssgp_suspend();
3029
3030 d := activate(as_nopaging_ps());
3031
3032 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3033 * nor any related paging requests */
3034 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3035
3036 deactivate(d);
3037
3038 /* resume GPRS */
3039 f_bssgp_resume(susp_ref);
3040
3041 /* now data should be flowing again */
3042 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3043}
3044testcase TC_suspend_resume() runs on test_CT {
3045 var BSSGP_ConnHdlr vc_conn;
3046 f_init();
3047 f_sleep(1.0);
3048 vc_conn := f_start_handler(refers(f_TC_suspend_resume), testcasename(), g_gb, 49);
3049 vc_conn.done;
3050 f_cleanup();
3051}
3052
3053/* SUSPEND, then RAU: data expected to flow after implicit resume */
3054private function f_TC_suspend_rau(charstring id) runs on BSSGP_ConnHdlr {
3055 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3056 var default d;
3057
3058 /* first perform regular attach */
3059 f_TC_attach(id);
3060 /* then activate PDP context */
3061 f_pdp_ctx_act(apars);
3062 /* then transceive a downlink PDU */
3063 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3064
3065 /* now suspend GPRS */
3066 f_bssgp_suspend();
3067
3068 d := activate(as_nopaging_ps());
3069
3070 /* at this point we don't expect any downlink traffic at all, neither actual LLC/SNDCP data,
3071 * nor any related paging requests */
3072 f_gtpu_xceive_mt(apars, f_rnd_octstring(100), expect_fwd := false);
3073
3074 deactivate(d);
3075
3076 /* perform RAU (implicit RESUME) */
3077 f_routing_area_update(g_pars.ra);
3078
3079 /* now data should be flowing again */
3080 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3081
3082}
3083testcase TC_suspend_rau() runs on test_CT {
3084 var BSSGP_ConnHdlr vc_conn;
3085 f_init();
3086 f_sleep(1.0);
3087 vc_conn := f_start_handler(refers(f_TC_suspend_rau), testcasename(), g_gb, 50);
3088 vc_conn.done;
3089 f_cleanup();
3090}
3091
3092
3093/* wait for T3314 expiration and check that PS PAGING is created on DL PDU */
3094private function f_TC_paging_ps(charstring id) runs on BSSGP_ConnHdlr {
3095 var PdpActPars apars := valueof(t_PdpActPars(mp_ggsn_ip));
3096 var default d;
3097
3098 /* first perform regular attach */
3099 f_TC_attach(id);
3100 /* then activate PDP context */
3101 f_pdp_ctx_act(apars);
3102 /* then transceive a downlink PDU */
3103 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3104
3105 /* now wait for T3314 expiration (test_CT below has reduced it to 3s) */
3106 f_sleep(5.0);
3107
3108 /* now data should be flowing again, but with PS PAGING */
3109 f_gtpu_xceive_mt(apars, f_rnd_octstring(100));
3110 BSSGP_SIG[0].receive(tr_BSSGP_PS_PAGING(?));
3111
3112 /* FIXME: simulate paging response */
3113 /* FIXME: verify PDU actually arrives only after paging response was successful */
3114
3115}
3116testcase TC_paging_ps() runs on test_CT {
3117 var BSSGP_ConnHdlr vc_conn;
3118 f_init();
3119 f_vty_config(SGSNVTY, "sgsn", "timer 3314 3");
3120 f_sleep(1.0);
3121 vc_conn := f_start_handler(refers(f_TC_paging_ps), testcasename(), g_gb, 51);
3122 vc_conn.done;
3123 f_vty_config(SGSNVTY, "sgsn", "timer 3314 default");
3124 f_cleanup();
3125}
3126
3127
3128
3129
3130
Harald Welte5ac31492018-02-15 20:39:13 +01003131control {
Harald Welte5b7c8122018-02-16 21:48:17 +01003132 execute( TC_attach() );
Neels Hofmeyr8df7d152018-03-14 19:03:28 +01003133 execute( TC_attach_mnc3() );
Neels Hofmeyr0ecb2e32018-04-30 15:13:55 +02003134 execute( TC_attach_umts_aka_umts_res() );
3135 execute( TC_attach_umts_aka_gsm_sres() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003136 execute( TC_attach_auth_id_timeout() );
3137 execute( TC_attach_auth_sai_timeout() );
Harald Weltefe253882018-02-17 09:25:00 +01003138 execute( TC_attach_auth_sai_reject() );
Harald Welte5b7c8122018-02-16 21:48:17 +01003139 execute( TC_attach_gsup_lu_timeout() );
Harald Welteb7c14e92018-02-17 09:29:16 +01003140 execute( TC_attach_gsup_lu_reject() );
Harald Welte3823e2e2018-02-16 21:53:48 +01003141 execute( TC_attach_combined() );
Harald Welte76dee092018-02-16 22:12:59 +01003142 execute( TC_attach_accept_all() );
Harald Welteb2124b22018-02-16 22:26:56 +01003143 execute( TC_attach_closed() );
Alexander Couzens667dd7f2018-06-12 16:24:01 +02003144 execute( TC_attach_no_imei_response() );
Alexander Couzens53f20562018-06-12 16:24:12 +02003145 execute( TC_attach_no_imsi_response() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003146 execute( TC_attach_closed_add_vty(), 20.0 );
3147 execute( TC_attach_check_subscriber_list(), 20.0 );
3148 execute( TC_attach_detach_check_subscriber_list(), 20.0 );
Alexander Couzens0085bd72018-06-12 19:08:44 +02003149 execute( TC_attach_check_complete_resend() );
Alexander Couzensd81876a2018-08-07 12:43:16 +02003150 execute( TC_hlr_location_cancel_request_update(), 20.0 );
3151 execute( TC_hlr_location_cancel_request_withdraw(), 20.0 );
3152 execute( TC_hlr_location_cancel_request_unknown_subscriber_withdraw(), 20.0 );
3153 execute( TC_hlr_location_cancel_request_unknown_subscriber_update(), 20.0 );
Harald Welte04683d02018-02-16 22:43:45 +01003154 execute( TC_rau_unknown() );
Harald Welte91636de2018-02-17 10:16:14 +01003155 execute( TC_attach_rau() );
Alexander Couzensbfda9212018-07-31 03:17:33 +02003156 execute( TC_attach_rau_a_a() );
Alexander Couzensbe837bd2018-07-31 04:20:11 +02003157 execute( TC_attach_rau_a_b() );
Alexander Couzens0c6324f2018-09-14 16:37:04 +02003158 execute( TC_attach_usim_resync() );
Harald Welte6abb9fe2018-02-17 15:24:48 +01003159 execute( TC_detach_unknown_nopoweroff() );
3160 execute( TC_detach_unknown_poweroff() );
3161 execute( TC_detach_nopoweroff() );
3162 execute( TC_detach_poweroff() );
Harald Welteeded9ad2018-02-17 20:57:34 +01003163 execute( TC_attach_pdp_act() );
Harald Welte835b15f2018-02-18 14:39:11 +01003164 execute( TC_pdp_act_unattached() );
Harald Welte37692d82018-02-18 15:21:34 +01003165 execute( TC_attach_pdp_act_user() );
Harald Welte5b5ca1b2018-02-18 21:25:03 +01003166 execute( TC_attach_pdp_act_ggsn_reject() );
Harald Welte6f203162018-02-18 22:04:55 +01003167 execute( TC_attach_pdp_act_user_deact_mo() );
Harald Welte57b9b7f2018-02-18 22:28:13 +01003168 execute( TC_attach_pdp_act_user_deact_mt() );
Pau Espin Pedrol2a3302a2019-08-15 16:01:20 +02003169 execute( TC_attach_pdp_act_deact_dup() );
Alexander Couzens187ad5d2018-05-02 19:31:10 +02003170 execute( TC_attach_second_attempt() );
Pau Espin Pedrolfcec9142019-08-28 17:33:46 +02003171 execute( TC_attach_echo_timeout() );
Pau Espin Pedrol94013452018-07-17 15:50:21 +02003172 execute( TC_attach_restart_ctr_echo() );
3173 execute( TC_attach_restart_ctr_create() );
Pau Espin Pedrol72edc8a2018-07-16 15:10:08 +02003174 execute( TC_attach_pdp_act_deact_mt_t3395_expire() );
Pau Espin Pedrole6f071f2019-05-29 13:02:42 +02003175 execute( TC_attach_pdp_act_deact_gtp_retrans() );
3176 execute( TC_attach_pdp_act_deact_gtp_retrans_resp() );
Pau Espin Pedrol482dde62018-07-18 13:47:42 +02003177 execute( TC_attach_pdp_act_user_error_ind_ggsn() );
Alexander Couzens6bee0872019-05-11 01:48:50 +02003178 execute( TC_attach_pdp_act_gmm_detach() );
Alexander Couzenscf3c93d2018-08-07 19:48:27 +02003179 execute( TC_attach_gmm_attach_req_while_gmm_attach() );
Harald Weltea05b8072019-04-23 22:35:05 +02003180
Harald Welte2aaac1b2019-05-02 10:02:53 +02003181 execute( TC_xid_empty_l3() );
3182 execute( TC_xid_n201u() );
3183
Harald Weltea05b8072019-04-23 22:35:05 +02003184 execute( TC_llc_null() );
Harald Welte645a1512019-04-23 23:18:23 +02003185 execute( TC_llc_sabm_dm_llgmm() );
3186 execute( TC_llc_sabm_dm_ll5() );
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003187
Harald Welte8e5932e2020-06-17 22:12:54 +02003188 execute( TC_suspend_nopaging() );
3189 execute( TC_suspend_resume() );
3190 execute( TC_suspend_rau() );
3191 execute( TC_paging_ps() );
3192
Pau Espin Pedrolce571b52019-11-08 18:32:28 +01003193 /* At the end, may crash osmo-sgsn, see OS#3957, OS#4245 */
3194 execute( TC_attach_req_id_req_ra_update() );
Harald Welte5ac31492018-02-15 20:39:13 +01003195}
Harald Welte96a33b02018-02-04 10:36:22 +01003196
3197
3198
3199}